home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / nsprpub / pr / tests / threads.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  5.8 KB  |  231 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /*
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  * 
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  * 
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. #include "nspr.h"
  20. #include "prinrval.h"
  21. #include "plgetopt.h"
  22. #include "pprthred.h"
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26.  
  27. #ifdef XP_MAC
  28. #include "prlog.h"
  29. #define printf PR_LogPrint
  30. extern void SetupMacPrintfLog(char *logFile);
  31. #endif
  32.  
  33. PRMonitor *mon;
  34. PRInt32 count, iterations, alive;
  35.  
  36. PRBool debug_mode = PR_FALSE, passed = PR_TRUE;
  37.  
  38. void 
  39. PR_CALLBACK
  40. ReallyDumbThread(void *arg)
  41. {
  42.     return;
  43. }
  44.  
  45. void
  46. PR_CALLBACK
  47. DumbThread(void *arg)
  48. {
  49.     PRInt32 tmp = (PRInt32)arg;
  50.     PRThreadScope scope = (PRThreadScope)tmp;
  51.     PRThread *thr;
  52.  
  53.     thr = PR_CreateThread(PR_USER_THREAD,
  54.                           ReallyDumbThread,
  55.                           NULL,
  56.                           PR_PRIORITY_NORMAL,
  57.                           scope,
  58.                           PR_JOINABLE_THREAD,
  59.                           0);
  60.  
  61.     if (!thr) {
  62.         if (debug_mode) {
  63.             printf("Could not create really dumb thread (%d, %d)!\n",
  64.                     PR_GetError(), PR_GetOSError());
  65.         }
  66.         passed = PR_FALSE;
  67.     } else {
  68.         PR_JoinThread(thr);
  69.     }
  70.     PR_EnterMonitor(mon);
  71.     alive--;
  72.     PR_Notify(mon);
  73.     PR_ExitMonitor(mon);
  74. }
  75.  
  76. static void CreateThreads(PRThreadScope scope1, PRThreadScope scope2)
  77. {
  78.     PRThread *thr;
  79.     int n;
  80.  
  81.     alive = 0;
  82.     mon = PR_NewMonitor();
  83.  
  84.     alive = count;
  85.     for (n=0; n<count; n++) {
  86.         thr = PR_CreateThread(PR_USER_THREAD,
  87.                               DumbThread, 
  88.                               (void *)scope2, 
  89.                               PR_PRIORITY_NORMAL,
  90.                               scope1,
  91.                               PR_UNJOINABLE_THREAD,
  92.                               0);
  93.         if (!thr) {
  94.             if (debug_mode) {
  95.                 printf("Could not create dumb thread (%d, %d)!\n",
  96.                         PR_GetError(), PR_GetOSError());
  97.             }
  98.             passed = PR_FALSE;
  99.             alive--;
  100.         }
  101.          
  102.         PR_Sleep(0);
  103.     }
  104.  
  105.     /* Wait for all threads to exit */
  106.     PR_EnterMonitor(mon);
  107.     while (alive) {
  108.         PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
  109.     }
  110.  
  111.     PR_ExitMonitor(mon);
  112.     PR_DestroyMonitor(mon);
  113. }
  114.  
  115. static void CreateThreadsUU(void)
  116. {
  117.     CreateThreads(PR_LOCAL_THREAD, PR_LOCAL_THREAD);
  118. }
  119.  
  120. static void CreateThreadsUK(void)
  121. {
  122.     CreateThreads(PR_LOCAL_THREAD, PR_GLOBAL_THREAD);
  123. }
  124.  
  125. static void CreateThreadsKU(void)
  126. {
  127.     CreateThreads(PR_GLOBAL_THREAD, PR_LOCAL_THREAD);
  128. }
  129.  
  130. static void CreateThreadsKK(void)
  131. {
  132.     CreateThreads(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD);
  133. }
  134.  
  135. /************************************************************************/
  136.  
  137. static void Measure(void (*func)(void), const char *msg)
  138. {
  139.     PRIntervalTime start, stop;
  140.     double d;
  141.  
  142.     start = PR_IntervalNow();
  143.     (*func)();
  144.     stop = PR_IntervalNow();
  145.  
  146.     if (debug_mode)
  147.     {
  148.         d = (double)PR_IntervalToMicroseconds(stop - start);
  149.         printf("%40s: %6.2f usec\n", msg, d / count);
  150.     }
  151. }
  152.  
  153. int main(int argc, char **argv)
  154. {
  155.     int index;
  156.  
  157.     PR_STDIO_INIT();
  158.     PR_Init(PR_USER_THREAD, PR_PRIORITY_HIGH, 0);
  159.     
  160.     {
  161.         PLOptStatus os;
  162.         PLOptState *opt = PL_CreateOptState(argc, argv, "dc:i:");
  163.         while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
  164.         {
  165.             if (PL_OPT_BAD == os) continue;
  166.             switch (opt->option)
  167.             {
  168.             case 'd':  /* debug mode */
  169.                 debug_mode = PR_TRUE;
  170.                 break;
  171.             case 'c':  /* loop counter */
  172.                 count = atoi(opt->value);
  173.                 break;
  174.             case 'i':  /* loop counter */
  175.                 iterations = atoi(opt->value);
  176.                 break;
  177.              default:
  178.                 break;
  179.             }
  180.         }
  181.         PL_DestroyOptState(opt);
  182.     }
  183.  
  184. #ifdef XP_MAC
  185.     SetupMacPrintfLog("threads.log");
  186.     count = 10;
  187.     iterations = 10;
  188.     debug_mode = PR_TRUE;
  189. #else
  190.     if (0 == count) count = 50;
  191.     if (0 == iterations) iterations = 10;
  192.  
  193. #endif
  194.  
  195.     if (debug_mode)
  196.     {
  197.     printf("\
  198. ** Tests lots of thread creations.  \n\
  199. ** Create %ld native threads %ld times. \n\
  200. ** Create %ld user threads %ld times \n", iterations,count,iterations,count);
  201.     }
  202.  
  203.     for (index=0; index<iterations; index++) {
  204.         Measure(CreateThreadsUU, "Create user/user threads");
  205.         Measure(CreateThreadsUK, "Create user/native threads");
  206.         Measure(CreateThreadsKU, "Create native/user threads");
  207.         Measure(CreateThreadsKK, "Create native/native threads");
  208.     }
  209.  
  210.     if (debug_mode) printf("\nNow switch to recycling threads \n\n");
  211.     PR_SetThreadRecycleMode(1);
  212.  
  213.     for (index=0; index<iterations; index++) {
  214.         Measure(CreateThreadsUU, "Create user/user threads");
  215.         Measure(CreateThreadsUK, "Create user/native threads");
  216.         Measure(CreateThreadsKU, "Create native/user threads");
  217.         Measure(CreateThreadsKK, "Create native/native threads");
  218.     }
  219.  
  220.  
  221.     printf("%s\n", ((passed) ? "PASS" : "FAIL"));
  222.  
  223.     PR_Cleanup();
  224.  
  225.     if (passed) {
  226.         return 0;
  227.     } else {
  228.         return 1;
  229.     }
  230. }
  231.