Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Functions | Variables
lockfile.c File Reference
#include "plgetopt.h"
#include "prcmon.h"
#include "prerror.h"
#include "prinit.h"
#include "prinrval.h"
#include "prlock.h"
#include "prlog.h"
#include "prmon.h"
#include "prthread.h"
#include "prtypes.h"
#include "private/pprio.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

Go to the source code of this file.

Classes

struct  LockContentious_s

Defines

#define LOCKFILE   "prlock.fil"

Typedefs

typedef struct LockContentious_s LockContentious_t

Functions

static PRIntervalTime NonContentiousLock (PRInt32 loops)
static void PR_CALLBACK LockContender (void *arg)
static PRIntervalTime ContentiousLock (PRInt32 loops)
static PRIntervalTime Test (const char *msg, PRIntervalTime(*test)(PRInt32 loops), PRInt32 loops, PRIntervalTime overhead)
int main (int argc, char **argv)
 The Xalan testcases app.

Variables

PRIntn failed_already = 0
PRIntn debug_mode
static const PRIntervalTime contention_interval = 50
static LockContentious_t contention

Class Documentation

struct LockContentious_s

Definition at line 103 of file lock.c.

Collaboration diagram for LockContentious_s:
Class Members
PRUint32 contender
PRUint32 contentious
PRIntervalTime interval
PRInt32 loops
PRLock * ml
PRIntervalTime overhead

Define Documentation

#define LOCKFILE   "prlock.fil"

Definition at line 97 of file lockfile.c.


Typedef Documentation


Function Documentation

static PRIntervalTime ContentiousLock ( PRInt32  loops) [static]

Definition at line 146 of file lockfile.c.

{
    PRStatus status;
    PRThread *thread = NULL;
    PRIntervalTime overhead, timein = PR_IntervalNow();

    contention.loops = loops;
    contention.overhead = 0;
    contention.ml = PR_NewLock();
    contention.interval = contention_interval;
    thread = PR_CreateThread(
        PR_USER_THREAD, LockContender, &contention,
        PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
    PR_ASSERT(thread != NULL);

    overhead = PR_IntervalNow() - timein;

    while (contention.loops > 0)
    {
        PR_Lock(contention.ml);
        contention.overhead += contention.interval;
        PR_Sleep(contention.interval);
        PR_Unlock(contention.ml);
    }

    timein = PR_IntervalNow();
    status = PR_JoinThread(thread);
    PR_DestroyLock(contention.ml);
    overhead += (PR_IntervalNow() - timein);
    return overhead + contention.overhead;
}  /* ContentiousLock */

Here is the call graph for this function:

Here is the caller graph for this function:

static void PR_CALLBACK LockContender ( void arg) [static]

Definition at line 120 of file lockfile.c.

{
    LockContentious_t *contention = (LockContentious_t*)arg;
    PRFileDesc *_lockfile;
    while (contention->loops-- > 0)
    {
        _lockfile = PR_Open(LOCKFILE, PR_CREATE_FILE|PR_RDWR, 0666);
        if (!_lockfile) {
            if (debug_mode) printf(
                "could not create lockfile: %d [%d]\n",
                PR_GetError(), PR_GetOSError());
            break;
        }
        PR_LockFile(_lockfile);
        PR_Sleep(contention->interval);
        PR_UnlockFile(_lockfile);
        PR_Close(_lockfile);
    }

}  /* LockContender */

Here is the call graph for this function:

Here is the caller graph for this function:

int main ( int  argc,
char **  argv 
)

The Xalan testcases app.

Definition at line 210 of file lockfile.c.

{
    PRIntervalTime duration;
    PRUint32 cpu, cpus = 2;
    PRInt32 loops = 100;

       
       /* The command line argument: -d is used to determine if the test is being run
       in debug mode. The regress tool requires only one line output:PASS or FAIL.
       All of the printfs associated with this test has been handled with a if (debug_mode)
       test.
       Usage: test_name -d
       */
       PLOptStatus os;
       PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
       while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
    {
              if (PL_OPT_BAD == os) continue;
        switch (opt->option)
        {
        case 'd':  /* debug mode */
                     debug_mode = 1;
            break;
         default:
            break;
        }
    }
       PL_DestroyOptState(opt);

 /* main test */
       
    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
    PR_STDIO_INIT();

#ifdef XP_MAC
       SetupMacPrintfLog("lockfile.log");
       debug_mode = 1;
#endif

    if (argc > 1) loops = atoi(argv[1]);
    if (loops == 0) loops = 100;
    if (debug_mode) printf("Lock: Using %d loops\n", loops);

    cpus = (argc < 3) ? 2 : atoi(argv[2]);
    if (cpus == 0) cpus = 2;
    if (debug_mode) printf("Lock: Using %d cpu(s)\n", cpus);


    for (cpu = 1; cpu <= cpus; ++cpu)
    {
        if (debug_mode) printf("\nLockFile: Using %d CPU(s)\n", cpu);
        PR_SetConcurrency(cpu);
        
        duration = Test("LockFile non-contentious locking/unlocking", NonContentiousLock, loops, 0);
        (void)Test("LockFile contentious locking/unlocking", ContentiousLock, loops, duration);
    }

    PR_Delete(LOCKFILE);  /* try to get rid of evidence */

    if (debug_mode) printf("%s: test %s\n", "Lock(mutex) test", ((failed_already) ? "failed" : "passed"));
       if(failed_already)   
              return 1;
       else
              return 0;
}  /* main */

Here is the call graph for this function:

static PRIntervalTime NonContentiousLock ( PRInt32  loops) [static]

Definition at line 101 of file lockfile.c.

{
    PRFileDesc *_lockfile;
    while (loops-- > 0)
    {
        _lockfile = PR_Open(LOCKFILE, PR_CREATE_FILE|PR_RDWR, 0666);
        if (!_lockfile) {
            if (debug_mode) printf(
                "could not create lockfile: %d [%d]\n",
                PR_GetError(), PR_GetOSError());
            return PR_INTERVAL_NO_TIMEOUT;
        }
        PR_LockFile(_lockfile);
        PR_UnlockFile(_lockfile);
        PR_Close(_lockfile);
    }
    return 0;
}  /* NonContentiousLock */

Here is the caller graph for this function:

static PRIntervalTime Test ( const char *  msg,
PRIntervalTime(*)(PRInt32 loops test,
PRInt32  loops,
PRIntervalTime  overhead 
) [static]

Definition at line 178 of file lockfile.c.

{ 
    /*
     * overhead - overhead not measured by the test.
     * duration - wall clock time it took to perform test.
     * predicted - extra time test says should not be counted 
     *
     * Time accountable to the test is duration - overhead - predicted
     * All times are Intervals and accumulated for all iterations.
     */
    PRFloat64 elapsed;
    PRIntervalTime accountable, duration;    
    PRUintn spaces = strlen(msg);
    PRIntervalTime timeout, timein = PR_IntervalNow();
    PRIntervalTime predicted = test(loops);
    timeout = PR_IntervalNow();
    duration = timeout - timein;
    accountable = duration - predicted;
    accountable -= overhead;
    elapsed = (PRFloat64)PR_IntervalToMicroseconds(accountable);
    if (debug_mode) printf("%s:", msg);
    while (spaces++ < 50) if (debug_mode) printf(" ");
    if ((PRInt32)accountable < 0) {
        if (debug_mode) printf("*****.** usecs/iteration\n");
    } else {
        if (debug_mode) printf("%8.2f usecs/iteration\n", elapsed/loops);
    }
    return duration;
}  /* Test */

Variable Documentation

Definition at line 144 of file lockfile.c.

Definition at line 88 of file lockfile.c.

PRIntn debug_mode

Definition at line 86 of file lockfile.c.

PRIntn failed_already = 0

Definition at line 85 of file lockfile.c.