Back to index

lightning-sunbird  0.9+nobinonly
Classes | Typedefs | Functions | Variables
bug1test.c File Reference
#include "prthread.h"
#include "prtypes.h"
#include "prinit.h"
#include "prmon.h"
#include "prlog.h"

Go to the source code of this file.

Classes

struct  Arg_s

Typedefs

typedef struct Arg_s Arg_t

Functions

void spin (PRInt32 aDelay)
void doWriteThread (void *arg)
void doReadThread (void *arg)
void fireThread (char *aName, void(*aProc)(void *arg), Arg_t *aArg)
int pseudoMain (int argc, char **argv, char *pad)
static void padStack (int argc, char **argv)
void main (int argc, char **argv)
 The Xalan testcases app.

Variables

PRMonitorgMonitor
PRInt32 gReading
PRInt32 gWriteWaiting
PRInt32 gReadWaiting
PRInt32 gCounter
PRInt32 gReads
PRInt32 gMaxReads
PRInt32 gMaxWriteWaits
PRInt32 gMaxReadWaits

Class Documentation

struct Arg_s

Definition at line 50 of file bug1test.c.

Class Members
PRInt32 a
PRInt32 b

Typedef Documentation

typedef struct Arg_s Arg_t

Function Documentation

void doReadThread ( void arg)

Definition at line 129 of file bug1test.c.

{
  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);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void doWriteThread ( void arg)

Definition at line 86 of file bug1test.c.

{
  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);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void fireThread ( char *  aName,
void(*)(void *arg aProc,
Arg_t aArg 
)

Definition at line 182 of file bug1test.c.

Here is the call graph for this function:

Here is the caller graph for this function:

void main ( int  argc,
char **  argv 
)

The Xalan testcases app.

Definition at line 249 of file bug1test.c.

Here is the call graph for this function:

static void padStack ( int  argc,
char **  argv 
) [static]

Definition at line 243 of file bug1test.c.

{
  char pad[512];      /* Work around bug in nspr on windoze */
  pseudoMain (argc, argv, pad);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pseudoMain ( int  argc,
char **  argv,
char *  pad 
)

Definition at line 190 of file bug1test.c.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void spin ( PRInt32  aDelay)

Definition at line 69 of file bug1test.c.

{
  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); 
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 60 of file bug1test.c.

Definition at line 64 of file bug1test.c.

Definition at line 66 of file bug1test.c.

Definition at line 65 of file bug1test.c.

Definition at line 55 of file bug1test.c.

Definition at line 56 of file bug1test.c.

Definition at line 63 of file bug1test.c.

Definition at line 58 of file bug1test.c.

Definition at line 57 of file bug1test.c.