📄 cvar2.c
字号:
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Netscape Portable Runtime (NSPR). * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. *//************************************************************************* 1996 - Netscape Communications Corporation**** Name: cvar2.c**** Description: Simple test creates several local and global threads;** half use a single,shared condvar, and the** other half have their own condvar. The main thread then loops** notifying them to wakeup. **** Modification History:** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.** The debug mode will print all of the printfs associated with this test.** The regress mode will be the default mode. Since the regress tool limits** the output to a one line status:PASS or FAIL,all of the printf statements** have been handled with an if (debug_mode) statement. ***********************************************************************/#include "nspr.h"#include "plerror.h"#include "plgetopt.h"#include <stdio.h>#include <stdlib.h>#include <string.h>int _debug_on = 0;#define DPRINTF(arg) if (_debug_on) printf arg#ifdef XP_MAC#include "prlog.h"#define printf PR_LogPrintextern void SetupMacPrintfLog(char *logFile);#endif#define DEFAULT_COUNT 100#define DEFAULT_THREADS 5PRInt32 count = DEFAULT_COUNT;typedef struct threadinfo { PRThread *thread; PRInt32 id; PRBool internal; PRInt32 *tcount; PRLock *lock; PRCondVar *cvar; PRIntervalTime timeout; PRInt32 loops; PRLock *exitlock; PRCondVar *exitcvar; PRInt32 *exitcount;} threadinfo;/*** Make exitcount, tcount static. for Win16.*/static PRInt32 exitcount=0;static PRInt32 tcount=0;/* Thread that gets notified; many threads share the same condvar */void PR_CALLBACKSharedCondVarThread(void *_info){ threadinfo *info = (threadinfo *)_info; PRInt32 index; for (index=0; index<info->loops; index++) { PR_Lock(info->lock); if (*info->tcount == 0) PR_WaitCondVar(info->cvar, info->timeout);#if 0 printf("shared thread %ld notified in loop %ld\n", info->id, index);#endif (*info->tcount)--; PR_Unlock(info->lock); PR_Lock(info->exitlock); (*info->exitcount)++; PR_NotifyCondVar(info->exitcvar); PR_Unlock(info->exitlock); }#if 0 printf("shared thread %ld terminating\n", info->id);#endif}/* Thread that gets notified; no other threads use the same condvar */void PR_CALLBACKPrivateCondVarThread(void *_info){ threadinfo *info = (threadinfo *)_info; PRInt32 index; for (index=0; index<info->loops; index++) { PR_Lock(info->lock); if (*info->tcount == 0) { DPRINTF(("PrivateCondVarThread: thread 0x%lx waiting on cvar = 0x%lx\n", PR_GetCurrentThread(), info->cvar)); PR_WaitCondVar(info->cvar, info->timeout); }#if 0 printf("solo thread %ld notified in loop %ld\n", info->id, index);#endif (*info->tcount)--; PR_Unlock(info->lock); PR_Lock(info->exitlock); (*info->exitcount)++; PR_NotifyCondVar(info->exitcvar);DPRINTF(("PrivateCondVarThread: thread 0x%lx notified exitcvar = 0x%lx cnt = %ld\n", PR_GetCurrentThread(), info->exitcvar,(*info->exitcount))); PR_Unlock(info->exitlock); }#if 0 printf("solo thread %ld terminating\n", info->id);#endif}void CreateTestThread(threadinfo *info, PRInt32 id, PRLock *lock, PRCondVar *cvar, PRInt32 loops, PRIntervalTime timeout, PRInt32 *tcount, PRLock *exitlock, PRCondVar *exitcvar, PRInt32 *exitcount, PRBool shared, PRThreadScope scope){ info->id = id; info->internal = (shared) ? PR_FALSE : PR_TRUE; info->lock = lock; info->cvar = cvar; info->loops = loops; info->timeout = timeout; info->tcount = tcount; info->exitlock = exitlock; info->exitcvar = exitcvar; info->exitcount = exitcount; info->thread = PR_CreateThread( PR_USER_THREAD, shared?SharedCondVarThread:PrivateCondVarThread, info, PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0); if (!info->thread) PL_PrintError("error creating thread\n");}void CondVarTestSUU(void *_arg){ PRInt32 arg = (PRInt32)_arg; PRInt32 index, loops; threadinfo *list; PRLock *sharedlock; PRCondVar *sharedcvar; PRLock *exitlock; PRCondVar *exitcvar; exitcount=0; tcount=0; list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4)); sharedlock = PR_NewLock(); sharedcvar = PR_NewCondVar(sharedlock); exitlock = PR_NewLock(); exitcvar = PR_NewCondVar(exitlock); /* Create the threads */ for(index=0; index<arg; ) { CreateTestThread(&list[index], index, sharedlock, sharedcvar, count, PR_INTERVAL_NO_TIMEOUT, &tcount, exitlock, exitcvar, &exitcount, PR_TRUE, PR_LOCAL_THREAD); index++; DPRINTF(("CondVarTestSUU: created thread 0x%lx\n",list[index].thread)); } for (loops = 0; loops < count; loops++) { /* Notify the threads */ for(index=0; index<(arg); index++) { PR_Lock(list[index].lock); (*list[index].tcount)++; PR_NotifyCondVar(list[index].cvar); PR_Unlock(list[index].lock); DPRINTF(("PrivateCondVarThread: thread 0x%lx notified cvar = 0x%lx\n", PR_GetCurrentThread(), list[index].cvar)); } /* Wait for threads to finish */ PR_Lock(exitlock); while(exitcount < arg) PR_WaitCondVar(exitcvar, PR_SecondsToInterval(60)); PR_ASSERT(exitcount >= arg); exitcount -= arg; PR_Unlock(exitlock); } /* Join all the threads */ for(index=0; index<(arg); index++) PR_JoinThread(list[index].thread); PR_DestroyCondVar(sharedcvar); PR_DestroyLock(sharedlock); PR_DestroyCondVar(exitcvar); PR_DestroyLock(exitlock); PR_DELETE(list);}void CondVarTestSUK(void *_arg){ PRInt32 arg = (PRInt32)_arg; PRInt32 index, loops; threadinfo *list; PRLock *sharedlock; PRCondVar *sharedcvar; PRLock *exitlock; PRCondVar *exitcvar; exitcount=0; tcount=0; list = (threadinfo *)PR_MALLOC(sizeof(threadinfo) * (arg * 4)); sharedlock = PR_NewLock(); sharedcvar = PR_NewCondVar(sharedlock); exitlock = PR_NewLock(); exitcvar = PR_NewCondVar(exitlock); /* Create the threads */ for(index=0; index<arg; ) { CreateTestThread(&list[index], index, sharedlock, sharedcvar, count, PR_INTERVAL_NO_TIMEOUT, &tcount, exitlock, exitcvar, &exitcount, PR_TRUE, PR_GLOBAL_THREAD); index++; } for (loops = 0; loops < count; loops++) { /* Notify the threads */ for(index=0; index<(arg); index++) { PR_Lock(list[index].lock); (*list[index].tcount)++; PR_NotifyCondVar(list[index].cvar); PR_Unlock(list[index].lock); }#if 0 printf("wait for threads to be done\n");#endif /* Wait for threads to finish */ PR_Lock(exitlock); while(exitcount < arg) PR_WaitCondVar(exitcvar, PR_SecondsToInterval(60)); PR_ASSERT(exitcount >= arg); exitcount -= arg; PR_Unlock(exitlock);#if 0 printf("threads ready\n");#endif } /* Join all the threads */ for(index=0; index<(arg); index++) PR_JoinThread(list[index].thread); PR_DestroyCondVar(sharedcvar); PR_DestroyLock(sharedlock); PR_DestroyCondVar(exitcvar); PR_DestroyLock(exitlock); PR_DELETE(list);}void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -