home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / nsprpub / lib / msgc / tests / thrashgc.c < prev   
Encoding:
C/C++ Source or Header  |  1998-04-08  |  6.4 KB  |  256 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. ** Name: thrashgc
  21. **
  22. ** Description: test garbace collection functions.
  23. **
  24. ** Modification History:
  25. ** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
  26. **             The debug mode will print all of the printfs associated with this test.
  27. **             The regress mode will be the default mode. Since the regress tool limits
  28. **           the output to a one line status:PASS or FAIL,all of the printf statements
  29. **             have been handled with an if (debug_mode) statement.
  30. ** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
  31. **            recognize the return code from tha main program.
  32. ***********************************************************************/
  33. /***********************************************************************
  34. ** Includes
  35. ***********************************************************************/
  36. #include "prthread.h"
  37. #include "prgc.h"
  38. #include "prprf.h"
  39. #include "prinrval.h"
  40. #include "prlock.h"
  41. #include "prinit.h"
  42. #include "prcvar.h"
  43.  
  44. #ifndef XP_MAC
  45. #include "private/pprthred.h"
  46. #else
  47. #include "pprthred.h"
  48. #endif
  49.  
  50. #include <stdio.h>
  51. #include <memory.h>
  52. #include <string.h>
  53.  
  54.  
  55. #ifdef XP_MAC
  56. #include "prlog.h"
  57. #define printf PR_LogPrint
  58. extern void SetupMacPrintfLog(char *logFile);
  59. #endif
  60.  
  61. PRIntn failed_already=0;
  62. PRIntn debug_mode;
  63.  
  64. static char* progname;
  65. static PRInt32 loops = 1000;
  66. static int tix1, tix2, tix3;
  67. static GCInfo* gcInfo;
  68. static PRLock* stderrLock;
  69.  
  70. typedef struct Type1 Type1;
  71. typedef struct Type2 Type2;
  72.  
  73. struct Type1 {
  74.   Type2* atwo;
  75.   Type1* next;
  76. };
  77.  
  78. struct Type2 {
  79.   void* buf;
  80. };
  81.  
  82. static void PR_CALLBACK ScanType1(void *obj) {
  83.   gcInfo->livePointer(((Type1 *)obj)->atwo);
  84.   gcInfo->livePointer(((Type1 *)obj)->next);
  85. }
  86.  
  87. static void PR_CALLBACK ScanType2(void *obj) {
  88.   gcInfo->livePointer(((Type2 *)obj)->buf);
  89. }
  90.  
  91. static GCType type1 = {
  92.     ScanType1
  93. };
  94.  
  95. static GCType type2 = {
  96.     ScanType2
  97. /*  (void (*)(void*)) ScanType2 */
  98. };
  99.  
  100. static GCType type3 = {
  101.   0
  102. };
  103.  
  104. Type1* NewType1(void) {
  105.     Type1* p = (Type1*) PR_AllocMemory(sizeof(Type1), tix1, PR_ALLOC_DOUBLE);
  106.     PR_ASSERT(p != NULL);
  107.     return p;
  108. }
  109.  
  110. Type2* NewType2(void) {
  111.     Type2* p = (Type2*) PR_AllocMemory(sizeof(Type2), tix2, PR_ALLOC_DOUBLE);
  112.     PR_ASSERT(p != NULL);
  113.     return p;
  114. }
  115.  
  116. void* NewBuffer(PRInt32 size) {
  117.     void* p = PR_AllocMemory(size, tix3, PR_ALLOC_DOUBLE);
  118.     PR_ASSERT(p != NULL);
  119.     return p;
  120. }
  121.  
  122. /* Allocate alot of garbage */
  123. static void PR_CALLBACK AllocStuff(void *unused) {
  124.   PRInt32 i;
  125.   void* danglingRefs[50];
  126.   PRIntervalTime start, end;
  127.   char msg[100];
  128.  
  129.   start = PR_IntervalNow();
  130.   for (i = 0; i < loops; i++) {
  131.     void* p;
  132.     if (i & 1) {
  133.       Type1* t1 = NewType1();
  134.       t1->atwo = NewType2();
  135.       t1->next = NewType1();
  136.       t1->atwo->buf = NewBuffer(100);
  137.       p = t1;
  138.     } else {
  139.       Type2* t2 = NewType2();
  140.       t2->buf = NewBuffer(i & 16383);
  141.       p = t2;
  142.     }
  143.     if ((i % 10) == 0) {
  144.       memmove(&danglingRefs[0], &danglingRefs[1], 49*sizeof(void*));
  145.       danglingRefs[49] = p;
  146.     }
  147.   }
  148.   end = PR_IntervalNow();
  149.   if (debug_mode) PR_snprintf(msg, sizeof(msg), "Thread %p: %ld allocations took %ld ms",
  150.           PR_GetCurrentThread(), loops,
  151.           PR_IntervalToMilliseconds((PRIntervalTime) (end - start)));
  152.   PR_Lock(stderrLock);
  153. #ifndef XP_MAC
  154.   fprintf(stderr, "%s\n", msg);
  155. #else
  156.   if (debug_mode) printf("%s\n", msg);
  157. #endif
  158.   PR_Unlock(stderrLock);
  159.   }
  160.  
  161. static void usage(char *progname) {
  162. #ifndef XP_MAC
  163.   fprintf(stderr, "Usage: %s [-t threads] [-l loops]\n", progname);
  164. #else
  165.   printf("Usage: %s [-t threads] [-l loops]\n", progname);
  166. #endif
  167.   exit(-1);
  168. }
  169.  
  170. static int realMain(int argc, char **argv, char *notused) {
  171.   int i;
  172.   int threads = 0;
  173.  
  174. #ifndef XP_MAC
  175.   progname = strrchr(argv[0], '/');
  176.   if (progname == 0) progname = argv[0];
  177.   for (i = 1; i < argc; i++) {
  178.     if (strcmp(argv[i], "-t") == 0) {
  179.       if (i == argc - 1) {
  180.     usage(progname);
  181.       }
  182.       threads = atoi(argv[++i]);
  183.       if (threads < 0) threads = 0;
  184.       if (threads > 10000) threads = 10000;
  185.       continue;
  186.     }
  187.     if (strcmp(argv[i], "-l") == 0) {
  188.       if (i == argc - 1) {
  189.     usage(progname);
  190.       }
  191.       loops = atoi(argv[++i]);
  192.       continue;
  193.     }
  194.     usage(progname);
  195.   }
  196. #else
  197.     threads = 50;
  198. #endif
  199.  
  200.   for (i = 0; i < threads; i++) {
  201.     PRThread* thread;
  202.  
  203.     /* XXXXX */
  204.     thread = PR_CreateThreadGCAble(PR_USER_THREAD,  /* thread type */
  205.                  AllocStuff,  /* start function */
  206.                  NULL,  /* arg */
  207.                  PR_PRIORITY_NORMAL,  /* priority */
  208.                  PR_LOCAL_THREAD,  /* thread scope */
  209.                  PR_UNJOINABLE_THREAD,  /* thread state */
  210.                  0);   /* stack size */
  211.     if (thread == 0) {
  212. #ifndef XP_MAC
  213.       fprintf(stderr, "%s: no more threads (only %d were created)\n",
  214.           progname, i);
  215. #else
  216.       printf("%s: no more threads (only %d were created)\n",
  217.           progname, i);
  218. #endif
  219.       break;
  220.     }
  221.   }
  222.   AllocStuff(NULL);
  223.   return 0;
  224. }
  225.  
  226. static int padMain(int argc, char **argv) {
  227.   char pad[512];
  228.   return realMain(argc, argv, pad);
  229. }
  230.  
  231. int main(int argc, char **argv) {
  232.   int rv;
  233.  
  234.   debug_mode = 1;
  235.   
  236.   PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
  237.   PR_SetThreadGCAble();
  238.  
  239. #ifdef XP_MAC
  240.   SetupMacPrintfLog("thrashgc.log");
  241.   debug_mode = 1;
  242. #endif
  243.  
  244.   PR_InitGC(0, 0, 0, PR_GLOBAL_THREAD);
  245.   PR_STDIO_INIT();
  246.   stderrLock = PR_NewLock();
  247.   tix1 = PR_RegisterType(&type1);
  248.   tix2 = PR_RegisterType(&type2);
  249.   tix3 = PR_RegisterType(&type3);
  250.   gcInfo = PR_GetGCInfo();
  251.   rv = padMain(argc, argv);
  252.   printf("PASS\n");
  253.   PR_Cleanup();
  254.   return rv;
  255. }
  256.