Example #1
0
int main(int argc,  char **argv)
{
    PRBool rv = PR_TRUE;
    PRIntervalTime duration;
    PRUint32 cpu, cpus = 2, loops = 100;

	
    PR_STDIO_INIT();
    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
    {
    	/* 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.
        Command line argument -l <num> sets the number of loops.
        Command line argument -c <num> sets the number of cpus.
        Usage: lock [-d] [-l <num>] [-c <num>]
    	*/
    	PLOptStatus os;
    	PLOptState *opt = PL_CreateOptState(argc, argv, "dl:c:");
    	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;
            case 'l':  /* number of loops */
                loops = atoi(opt->value);
                break;
            case 'c':  /* number of cpus */
                cpus = atoi(opt->value);
                break;
             default:
                break;
            }
        }
    	PL_DestroyOptState(opt);
    }

 /* main test */
    PR_SetConcurrency(8);

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

    if (loops == 0) loops = 100;
    if (debug_mode) printf("Lock: Using %d loops\n", loops);

    if (cpus == 0) cpus = 2;
    if (debug_mode) printf("Lock: Using %d cpu(s)\n", cpus);

    (void)Sleeper(10);  /* try filling in the caches */

    for (cpu = 1; cpu <= cpus; ++cpu)
    {
        if (debug_mode) printf("\nLock: Using %d CPU(s)\n", cpu);
        PR_SetConcurrency(cpu);

        duration = Test("Overhead of PR_Sleep", Sleeper, loops, 0);
        duration = 0;

        (void)Test("Lock creation/deletion", MakeLock, loops, 0);
        (void)Test("Lock non-contentious locking/unlocking", NonContentiousLock, loops, 0);
        (void)Test("Lock contentious locking/unlocking", ContentiousLock, loops, duration);
        (void)Test("Monitor creation/deletion", MakeMonitor, loops, 0);
        (void)Test("Monitor non-contentious locking/unlocking", NonContentiousMonitor, loops, 0);
        (void)Test("Monitor contentious locking/unlocking", ContentiousMonitor, loops, duration);

        (void)Test("Cached monitor non-contentious locking/unlocking", NonContentiousCMonitor, loops, 0);
        (void)Test("Cached monitor contentious locking/unlocking", ContentiousCMonitor, loops, duration);

        (void)ReentrantMonitor(loops);
    }

    if (debug_mode) printf("%s: test %s\n", "Lock(mutex) test", ((rv) ? "passed" : "failed"));
	else {
		 if (!rv)
			 failed_already=1;
	}

	if(failed_already)	
	{
	    printf("FAIL\n"); 
		return 1;
    } 
	else
    {
	    printf("PASS\n"); 
		return 0;
    }

}  /* main */
static int
WaitForPossession(ConstUnicode lockDir,      // IN:
                  ConstUnicode fileName,     // IN:
                  LockValues *memberValues,  // IN:
                  LockValues *myValues)      // IN:
{
   int err = 0;

   ASSERT(lockDir);
   ASSERT(fileName);

   /* "Win" or wait? */
   if (((memberValues->lamportNumber < myValues->lamportNumber) ||
       ((memberValues->lamportNumber == myValues->lamportNumber) &&
          (Unicode_Compare(memberValues->memberName,
                           myValues->memberName) < 0))) &&
        ((strcmp(memberValues->lockType, LOCK_EXCLUSIVE) == 0) ||
         (strcmp(myValues->lockType, LOCK_EXCLUSIVE) == 0))) {
      Unicode path;
      uint32 loopCount;
      Bool   thisMachine; 

      thisMachine = FileLockMachineIDMatch(myValues->machineID,
                                           memberValues->machineID);

      loopCount = 0;

      path = Unicode_Join(lockDir, DIRSEPS, fileName, NULL);

      while ((err = Sleeper(myValues, &loopCount)) == 0) {
         /* still there? */
         err = FileAttributesRobust(path, NULL);
         if (err != 0) {
            if (err == ENOENT) {
               /* Not there anymore; locker unlocked or timed out */
               err = 0;
            }

            break;
         }

         /* still valid? */
         if (thisMachine && !FileLockValidOwner(memberValues->executionID,
                                                memberValues->payload)) {
            /* Invalid Execution ID; remove the member file */
            Warning(LGPFX" %s discarding file '%s'; invalid executionID.\n",
                    __FUNCTION__, UTF8(path));

            err = RemoveLockingFile(lockDir, fileName);
            break;
         }
      }

      /*
       * Log the disposition of each timeout for all non "try lock" locking
       * attempts. This can assist in debugging locking problems.
       */

      if ((myValues->msecMaxWaitTime != FILELOCK_TRYLOCK_WAIT) &&
          (err == EAGAIN)) {
         if (thisMachine) {
            Log(LGPFX" %s timeout on '%s' due to a local process (%s)\n",
                    __FUNCTION__, UTF8(path), memberValues->executionID);
         } else {
            Log(LGPFX" %s timeout on '%s' due to another machine (%s)\n",
                    __FUNCTION__, UTF8(path), memberValues->machineID);
         }
      }

      Unicode_Free(path);
   }

   return err;
}