home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / nsprpub / lib / msgc / tests / gc1.c next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  5.9 KB  |  239 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. /***********************************************************************
  20. ** Includes
  21. ***********************************************************************/
  22. /* Used to get the command line option */
  23. #include "plgetopt.h"
  24.  
  25. #include "prgc.h"
  26. #include "prinit.h"
  27. #include "prmon.h"
  28. #include "prinrval.h"
  29. #ifndef XP_MAC
  30. #include "private/pprthred.h"
  31. #else
  32. #include "pprthred.h"
  33. #endif
  34.  
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37.  
  38. #ifdef XP_MAC
  39. #include "prlog.h"
  40. #define printf PR_LogPrint
  41. extern void SetupMacPrintfLog(char *logFile);
  42. #endif
  43.  
  44. static PRMonitor *mon;
  45. static PRInt32 threads, waiting, iterations;
  46. static PRInt32 scanCount, finalizeCount, freeCount;
  47.  
  48. PRIntn failed_already=0;
  49. PRIntn debug_mode;
  50.  
  51.  
  52. typedef struct Array {
  53.     PRUintn size;
  54.     void *body[1];
  55. } Array;
  56.  
  57. int arrayTypeIndex;
  58.  
  59. static void PR_CALLBACK ScanArray(void *a)
  60. {
  61. /*    printf ("In ScanArray a = %X size = %d \n", a, a->size); */
  62.     scanCount++;
  63. }
  64.  
  65. static void PR_CALLBACK FinalizeArray(void *a)
  66. {
  67. /*    printf ("In FinalizeArray a = %X size = %d \n", a, a->size); */    
  68.     finalizeCount++;
  69. }
  70.  
  71. static void PR_CALLBACK FreeArray(void *a)
  72. {
  73. /*    printf ("In FreeArray\n");    */
  74.     freeCount++;
  75. }
  76.  
  77. static Array *NewArray(PRUintn size)
  78. {
  79.     Array *a;
  80.  
  81.     a = (Array *)PR_AllocMemory(sizeof(Array) + size*sizeof(void*) - 1*sizeof(void*),
  82.                        arrayTypeIndex, PR_ALLOC_CLEAN);
  83.  
  84. /*    printf ("In NewArray a = %X \n", a); */    
  85.  
  86.     if (a)
  87.         a->size = size;
  88.     return a;
  89. }
  90.  
  91. GCType arrayType = {
  92.     ScanArray,
  93.     FinalizeArray,
  94.     0,
  95.     0,
  96.     FreeArray,
  97.     0
  98. };
  99.  
  100. static void Initialize(void)
  101. {
  102.     PR_InitGC(0, 0, 0, PR_GLOBAL_THREAD);
  103.     arrayTypeIndex = PR_RegisterType(&arrayType);
  104. }
  105.  
  106. static void PR_CALLBACK AllocateLikeMad(void *arg)
  107. {
  108.     Array *prev;
  109.     PRInt32 i;
  110.     PRInt32 count;
  111.  
  112.     count = (PRInt32)arg;
  113.     prev = 0;
  114.     for (i = 0; i < count; i++) {
  115.         Array *leak = NewArray(i & 511);
  116.         if ((i & 1023) == 0) {
  117.             prev = 0;                   /* forget */
  118.         } else {
  119.             if (i & 1) {
  120.                 prev = leak;            /* remember */
  121.             }
  122.         }
  123.     }
  124.     PR_EnterMonitor(mon);
  125.     waiting++;
  126.     PR_Notify(mon);
  127.     PR_ExitMonitor(mon);
  128. }
  129.  
  130. int main(int argc, char **argv)
  131. {
  132.     PRIntervalTime start, stop, usec;
  133.     double d;
  134.     PRIntn i, totalIterations;
  135.     /* The command line argument: -d is used to determine if the test is being run
  136.     in debug mode. The regress tool requires only one line output:PASS or FAIL.
  137.     All of the printfs associated with this test has been handled with a if (debug_mode)
  138.     test.
  139.     Usage: test_name -d
  140.     */
  141.     PLOptStatus os;
  142.     PLOptState *opt = PL_CreateOptState(argc, argv, "dt:c:");
  143.  
  144.     threads = 10;
  145.     iterations = 100;
  146.  
  147.     while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
  148.     {
  149.         if (PL_OPT_BAD == os) {
  150.             fprintf(stderr, "Invalid command-line option\n");
  151.             exit(1);
  152.         }
  153.         switch (opt->option)
  154.         {
  155.         case 'd':  /* debug mode */
  156.             debug_mode = 1;
  157.             break;
  158.         case 't':  /* number of threads */
  159.             threads = atoi(opt->value);
  160.             break;
  161.         case 'c':  /* iteration count */
  162.             iterations = atoi(opt->value);
  163.             break;
  164.         default:
  165.             break;
  166.         }
  167.     }
  168.     PL_DestroyOptState(opt);
  169.  
  170.     fprintf(stderr, "t is %ld, i is %ld\n", threads, iterations);
  171.     /* main test */
  172.  
  173.     PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 5);
  174.     PR_STDIO_INIT();
  175.     Initialize();
  176.  
  177. #ifdef XP_MAC
  178.     SetupMacPrintfLog("gc1.log");
  179.     debug_mode = 1;
  180. #endif
  181.  
  182.     /* Spin all of the allocator threads and then wait for them to exit */
  183.     start = PR_IntervalNow();
  184.     mon = PR_NewMonitor();
  185.     PR_EnterMonitor(mon);
  186.     waiting = 0;
  187.     for (i = 0; i < threads; i++) {
  188.         (void) PR_CreateThreadGCAble(PR_USER_THREAD,
  189.                                AllocateLikeMad, (void*)iterations,
  190.                               PR_PRIORITY_NORMAL,
  191.                               PR_LOCAL_THREAD,
  192.                               PR_UNJOINABLE_THREAD,
  193.                               0);
  194.     }
  195.     while (waiting != threads) {
  196.         PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
  197.     }
  198.     PR_ExitMonitor(mon);
  199.  
  200.     PR_GC();
  201.     PR_ForceFinalize();    
  202.  
  203.     totalIterations = iterations * threads;
  204. /*
  205.     if (scanCount != totalIterations)
  206.         printf ("scanCount discrepancy scanCount = %d totalIterations = %d \n", 
  207.             scanCount, totalIterations);
  208.     if (freeCount != totalIterations)
  209.         printf ("freeCount discrepancy freeCount = %d totalIterations = %d \n", 
  210.             freeCount, totalIterations);
  211.     if ((finalizeCount != totalIterations) && (finalizeCount != (totalIterations-1)))
  212.         printf ("finalizeCount discrepancy finalizeCount = %d totalIterations = %d \n", 
  213.             finalizeCount,totalIterations);
  214. */
  215.  
  216.     stop = PR_IntervalNow();
  217.     
  218.     usec = stop = stop - start;
  219.     d = (double)usec;
  220.  
  221.     if (debug_mode) printf("%40s: %6.2f usec\n", "GC allocation", d / (iterations * threads));
  222.     else {
  223.         if (d == 0.0) failed_already = PR_TRUE;
  224.  
  225.     }
  226.  
  227.     PR_Cleanup();
  228.     if(failed_already)    
  229.     {
  230.         printf("FAIL\n");
  231.         return 1;
  232.     }
  233.     else
  234.     {
  235.         printf("PASS\n");
  236.         return 0;
  237.     }
  238. }
  239.