Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Functions | Variables
rwlocktest.c File Reference
#include "nspr.h"
#include "plgetopt.h"
#include "prrwlock.h"

Go to the source code of this file.

Classes

struct  thread_args

Defines

#define DEFAULT_THREAD_CNT   4
#define DEFAULT_LOOP_CNT   100
#define TEST_ARRAY_SIZE   100

Typedefs

typedef struct thread_args thread_args

Functions

static void rwtest (void *args)
static void update_array (void)
static void check_array (void)
PRIntn main (PRIntn argc, char **argv)

Variables

static int _debug_on
static PRInt32array_A
static PRInt32array_B
static PRInt32array_C
PRFileDescoutput
PRFileDescerrhandle

Class Documentation

struct thread_args

Definition at line 63 of file rwlocktest.c.

Collaboration diagram for thread_args:
Class Members
PRInt32 loop_cnt
PRRWLock * rwlock

Define Documentation

Definition at line 72 of file rwlocktest.c.

Definition at line 71 of file rwlocktest.c.

Definition at line 73 of file rwlocktest.c.


Typedef Documentation

typedef struct thread_args thread_args

Function Documentation

static void check_array ( void  ) [static]

Definition at line 222 of file rwlocktest.c.

{
PRInt32 i;

       for (i=0; i < TEST_ARRAY_SIZE;i++)
              if (array_C[i] != (array_A[i] + array_B[i])) {
                     PR_fprintf(output, "Error - data check failed\n");
                     PR_ProcessExit(1);
              }
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRIntn main ( PRIntn  argc,
char **  argv 
)

Definition at line 75 of file rwlocktest.c.

{
    PRInt32 cnt;
       PRStatus rc;
       PRInt32 i;

       PRInt32 thread_cnt = DEFAULT_THREAD_CNT;
       PRInt32 loop_cnt = DEFAULT_LOOP_CNT;
       PRThread **threads;
       thread_args *params;
       PRRWLock      *rwlock1;

       PLOptStatus os;
       PLOptState *opt = PL_CreateOptState(argc, argv, "dt:c:");

       while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
    {
              if (PL_OPT_BAD == os) continue;
        switch (opt->option)
        {
        case 'd':  /* debug mode */
                     _debug_on = 1;
            break;
        case 't':  /* thread count */
            thread_cnt = atoi(opt->value);
            break;
        case 'c':  /* loop count */
            loop_cnt = atoi(opt->value);
            break;
         default:
            break;
        }
    }
       PL_DestroyOptState(opt);

       PR_SetConcurrency(4);

    output = PR_GetSpecialFD(PR_StandardOutput);
    errhandle = PR_GetSpecialFD(PR_StandardError);

       rwlock1 = PR_NewRWLock(0,"Lock 1");
       if (rwlock1 == NULL) {
              PR_fprintf(errhandle, "PR_NewRWLock failed - error %d\n",
                                                        PR_GetError());
              return 1;
       }

       threads = (PRThread**) PR_CALLOC(sizeof(PRThread*) * thread_cnt);
       params = (thread_args *) PR_CALLOC(sizeof(thread_args) * thread_cnt);

       /*
        * allocate and initialize data arrays
        */
       array_A =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE);
       array_B =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE);
       array_C =(PRInt32 *) PR_MALLOC(sizeof(PRInt32) * TEST_ARRAY_SIZE);
       cnt = 0;
       for (i=0; i < TEST_ARRAY_SIZE;i++) {
              array_A[i] = cnt++;
              array_B[i] = cnt++;
              array_C[i] = array_A[i] + array_B[i];
       }

       if (_debug_on)
              PR_fprintf(output,"%s: thread_cnt = %d loop_cnt = %d\n", argv[0],
                                                 thread_cnt, loop_cnt);
       for(cnt = 0; cnt < thread_cnt; cnt++) {
              PRThreadScope scope;

              params[cnt].rwlock = rwlock1;
              params[cnt].loop_cnt = loop_cnt;

              /*
               * create LOCAL and GLOBAL threads alternately
               */
              if (cnt & 1)
                     scope = PR_LOCAL_THREAD;
              else
                     scope = PR_GLOBAL_THREAD;

              threads[cnt] = PR_CreateThread(PR_USER_THREAD,
                                            rwtest, &params[cnt],
                                            PR_PRIORITY_NORMAL,
                                            scope,
                                            PR_JOINABLE_THREAD,
                                            0);
              if (threads[cnt] == NULL) {
                     PR_fprintf(errhandle, "PR_CreateThread failed - error %d\n",
                                                        PR_GetError());
                     PR_ProcessExit(2);
              }
              if (_debug_on)
                     PR_fprintf(output,"%s: created thread = 0x%x\n", argv[0],
                                                                      threads[cnt]);
       }

       for(cnt = 0; cnt < thread_cnt; cnt++) {
       rc = PR_JoinThread(threads[cnt]);
              PR_ASSERT(rc == PR_SUCCESS);

       }

       PR_DELETE(threads);
       PR_DELETE(params);

       PR_DELETE(array_A);  
       PR_DELETE(array_B);  
       PR_DELETE(array_C);  

       PR_DestroyRWLock(rwlock1);

       
       printf("PASS\n");
       return 0;
}

Here is the call graph for this function:

static void rwtest ( void args) [static]

Definition at line 191 of file rwlocktest.c.

{
    PRInt32 index;
       thread_args *arg = (thread_args *) args;


       for (index = 0; index < arg->loop_cnt; index++) {

              /*
               * verify sum, update arrays and verify sum again
               */

              PR_RWLock_Rlock(arg->rwlock);
              check_array();
              PR_RWLock_Unlock(arg->rwlock);

              PR_RWLock_Wlock(arg->rwlock);
              update_array();
              PR_RWLock_Unlock(arg->rwlock);

              PR_RWLock_Rlock(arg->rwlock);
              check_array();
              PR_RWLock_Unlock(arg->rwlock);
       }
       if (_debug_on)
              PR_fprintf(output,
              "Thread[0x%x] lock = 0x%x exiting\n",
                            PR_GetCurrentThread(), arg->rwlock);

}

Here is the call graph for this function:

Here is the caller graph for this function:

static void update_array ( void  ) [static]

Definition at line 233 of file rwlocktest.c.

{
PRInt32 i;

       for (i=0; i < TEST_ARRAY_SIZE;i++) {
              array_A[i] += i;
              array_B[i] -= i;
       }
}

Here is the caller graph for this function:


Variable Documentation

int _debug_on [static]

Definition at line 57 of file rwlocktest.c.

PRInt32* array_A [static]

Definition at line 59 of file rwlocktest.c.

PRInt32 * array_B [static]

Definition at line 59 of file rwlocktest.c.

PRInt32 * array_C [static]

Definition at line 59 of file rwlocktest.c.

Definition at line 69 of file rwlocktest.c.

Definition at line 68 of file rwlocktest.c.