⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bug1test.c

📁 Netscape NSPR库源码
💻 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. *//*Attached is a test program that uses the nspr1 to demonstrate a bugunder NT4.0. The fix has already been mentioned (add a ResetEvent justbefore leaving the critical section in _PR_CondWait in hwmon.c).*/#include "prthread.h"#include "prtypes.h"#include "prinit.h"#include "prmon.h"#include "prlog.h"typedef struct Arg_s{	PRInt32 a, b;} Arg_t;PRMonitor*  gMonitor;       // the monitorPRInt32     gReading;       // number of read locksPRInt32     gWriteWaiting;  // number of threads waiting for write lockPRInt32     gReadWaiting;   // number of threads waiting for read lockPRInt32     gCounter;       // a counter                            // statsPRInt32     gReads;         // number of successful readsPRInt32     gMaxReads;      // max number of simultaneous readsPRInt32     gMaxWriteWaits; // max number of writes that waited for readPRInt32     gMaxReadWaits;  // max number of reads that waited for write waitvoid spin (PRInt32 aDelay){  PRInt32 index;  PRInt32 delay = aDelay * 1000;  PR_Sleep(0);  // randomize delay a bit  delay = (delay / 2) + (PRInt32)((float)delay *	  ((float)rand () / (float)RAND_MAX));  for (index = 0; index < delay * 10; index++)	  // consume a bunch of cpu cycles    ;  PR_Sleep(0); }void  doWriteThread (void* arg){  PRInt32 last;  Arg_t *args = (Arg_t*)arg;  PRInt32 aWorkDelay = args->a, aWaitDelay = args->b;  PR_Sleep(0);  while (1)  {    // -- enter write lock    PR_EnterMonitor (gMonitor);    if (0 < gReading)     // wait for read locks to go away    {      PRIntervalTime fiveSecs = PR_SecondsToInterval(5);      gWriteWaiting++;      if (gWriteWaiting > gMaxWriteWaits) // stats        gMaxWriteWaits = gWriteWaiting;      while (0 < gReading)        PR_Wait (gMonitor, fiveSecs);      gWriteWaiting--;    }    // -- write lock entered    last = gCounter;    gCounter++;    spin (aWorkDelay);    PR_ASSERT (gCounter == (last + 1)); // test invariance    // -- exit write lock        //    if (0 < gReadWaiting)   // notify waiting reads (do it anyway to show off the CondWait bug)      PR_NotifyAll (gMonitor);    PR_ExitMonitor (gMonitor);    // -- write lock exited    spin (aWaitDelay);  }}void  doReadThread (void* arg){  PRInt32 last;  Arg_t *args = (Arg_t*)arg;  PRInt32 aWorkDelay = args->a, aWaitDelay = args->b;  PR_Sleep(0);  while (1)  {    // -- enter read lock    PR_EnterMonitor (gMonitor);     if (0 < gWriteWaiting)  // give up the monitor to waiting writes    {      PRIntervalTime fiveSecs = PR_SecondsToInterval(5);      gReadWaiting++;      if (gReadWaiting > gMaxReadWaits) // stats        gMaxReadWaits = gReadWaiting;      while (0 < gWriteWaiting)        PR_Wait (gMonitor, fiveSecs);      gReadWaiting--;    }    gReading++;    gReads++;   // stats    if (gReading > gMaxReads) // stats      gMaxReads = gReading;    PR_ExitMonitor (gMonitor);    // -- read lock entered    last = gCounter;    spin (aWorkDelay);    PR_ASSERT (gCounter == last); // test invariance    // -- exit read lock    PR_EnterMonitor (gMonitor);  // read unlock    gReading--;//    if ((0 == gReading) && (0 < gWriteWaiting))  // notify waiting writes  (do it anyway to show off the CondWait bug)      PR_NotifyAll (gMonitor);    PR_ExitMonitor (gMonitor);    // -- read lock exited    spin (aWaitDelay);  }}void fireThread (    char* aName, void (*aProc)(void *arg), Arg_t *aArg){  PRThread *thread = PR_CreateThread(	  PR_USER_THREAD, aProc, aArg, PR_PRIORITY_NORMAL,	  PR_LOCAL_THREAD, PR_UNJOINABLE_THREAD, 0);}int pseudoMain (int argc, char** argv, char *pad){  PRInt32 lastWriteCount  = gCounter;  PRInt32 lastReadCount   = gReads;  Arg_t a1 = {500, 250};  Arg_t a2 = {500, 500};  Arg_t a3 = {250, 500};  Arg_t a4 = {750, 250};  Arg_t a5 = {100, 750};  Arg_t a6 = {100, 500};  Arg_t a7 = {100, 750};  gMonitor = PR_NewMonitor ();  fireThread ("R1", doReadThread,   &a1);  fireThread ("R2", doReadThread,   &a2);  fireThread ("R3", doReadThread,   &a3);  fireThread ("R4", doReadThread,   &a4);  fireThread ("W1", doWriteThread,  &a5);  fireThread ("W2", doWriteThread,  &a6);  fireThread ("W3", doWriteThread,  &a7);  fireThread ("R5", doReadThread,   &a1);  fireThread ("R6", doReadThread,   &a2);  fireThread ("R7", doReadThread,   &a3);  fireThread ("R8", doReadThread,   &a4);  fireThread ("W4", doWriteThread,  &a5);  fireThread ("W5", doWriteThread,  &a6);  fireThread ("W6", doWriteThread,  &a7);    while (1)  {	PRInt32 writeCount, readCount;    PRIntervalTime fiveSecs = PR_SecondsToInterval(5);    PR_Sleep (fiveSecs);  // get out of the way    // print some stats, not threadsafe, informative only    writeCount = gCounter;    readCount   = gReads;    printf ("\ntick %d writes (+%d), %d reads (+%d) [max %d, %d, %d]",             writeCount, writeCount - lastWriteCount,            readCount, readCount - lastReadCount,             gMaxReads, gMaxWriteWaits, gMaxReadWaits);    lastWriteCount = writeCount;    lastReadCount = readCount;    gMaxReads = gMaxWriteWaits = gMaxReadWaits = 0;  }  return 0;}static void padStack (int argc, char** argv){  char pad[512];      /* Work around bug in nspr on windoze */  pseudoMain (argc, argv, pad);}void main (int argc, char **argv){  PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);  PR_STDIO_INIT();  padStack (argc, argv);}/* bug1test.c */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -