| Index: third_party/nspr/mozilla/nsprpub/lib/msgc/tests/gc1.c
|
| diff --git a/third_party/nspr/mozilla/nsprpub/lib/msgc/tests/gc1.c b/third_party/nspr/mozilla/nsprpub/lib/msgc/tests/gc1.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d6846235ba4af66a310498c8496148279fc913f4
|
| --- /dev/null
|
| +++ b/third_party/nspr/mozilla/nsprpub/lib/msgc/tests/gc1.c
|
| @@ -0,0 +1,257 @@
|
| +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
| +/* ***** BEGIN LICENSE BLOCK *****
|
| + * Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
| + *
|
| + * The contents of this file are subject to the Mozilla Public License Version
|
| + * 1.1 (the "License"); you may not use this file except in compliance with
|
| + * the License. You may obtain a copy of the License at
|
| + * http://www.mozilla.org/MPL/
|
| + *
|
| + * Software distributed under the License is distributed on an "AS IS" basis,
|
| + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
| + * for the specific language governing rights and limitations under the
|
| + * License.
|
| + *
|
| + * The Original Code is the Netscape Portable Runtime (NSPR).
|
| + *
|
| + * The Initial Developer of the Original Code is
|
| + * Netscape Communications Corporation.
|
| + * Portions created by the Initial Developer are Copyright (C) 1998-2000
|
| + * the Initial Developer. All Rights Reserved.
|
| + *
|
| + * Contributor(s):
|
| + *
|
| + * Alternatively, the contents of this file may be used under the terms of
|
| + * either the GNU General Public License Version 2 or later (the "GPL"), or
|
| + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
| + * in which case the provisions of the GPL or the LGPL are applicable instead
|
| + * of those above. If you wish to allow use of your version of this file only
|
| + * under the terms of either the GPL or the LGPL, and not to allow others to
|
| + * use your version of this file under the terms of the MPL, indicate your
|
| + * decision by deleting the provisions above and replace them with the notice
|
| + * and other provisions required by the GPL or the LGPL. If you do not delete
|
| + * the provisions above, a recipient may use your version of this file under
|
| + * the terms of any one of the MPL, the GPL or the LGPL.
|
| + *
|
| + * ***** END LICENSE BLOCK ***** */
|
| +
|
| +/***********************************************************************
|
| +** Includes
|
| +***********************************************************************/
|
| +/* Used to get the command line option */
|
| +#include "plgetopt.h"
|
| +
|
| +#include "prgc.h"
|
| +#include "prinit.h"
|
| +#include "prmon.h"
|
| +#include "prinrval.h"
|
| +#ifndef XP_MAC
|
| +#include "private/pprthred.h"
|
| +#else
|
| +#include "pprthred.h"
|
| +#endif
|
| +
|
| +#include <stdio.h>
|
| +#include <stdlib.h>
|
| +
|
| +#ifdef XP_MAC
|
| +#include "prlog.h"
|
| +#define printf PR_LogPrint
|
| +extern void SetupMacPrintfLog(char *logFile);
|
| +#endif
|
| +
|
| +static PRMonitor *mon;
|
| +static PRInt32 threads, waiting, iterations;
|
| +static PRInt32 scanCount, finalizeCount, freeCount;
|
| +
|
| +PRIntn failed_already=0;
|
| +PRIntn debug_mode;
|
| +
|
| +
|
| +typedef struct Array {
|
| + PRUintn size;
|
| + void *body[1];
|
| +} Array;
|
| +
|
| +int arrayTypeIndex;
|
| +
|
| +static void PR_CALLBACK ScanArray(void *a)
|
| +{
|
| +/* printf ("In ScanArray a = %X size = %d \n", a, a->size); */
|
| + scanCount++;
|
| +}
|
| +
|
| +static void PR_CALLBACK FinalizeArray(void *a)
|
| +{
|
| +/* printf ("In FinalizeArray a = %X size = %d \n", a, a->size); */
|
| + finalizeCount++;
|
| +}
|
| +
|
| +static void PR_CALLBACK FreeArray(void *a)
|
| +{
|
| +/* printf ("In FreeArray\n"); */
|
| + freeCount++;
|
| +}
|
| +
|
| +static Array *NewArray(PRUintn size)
|
| +{
|
| + Array *a;
|
| +
|
| + a = (Array *)PR_AllocMemory(sizeof(Array) + size*sizeof(void*) - 1*sizeof(void*),
|
| + arrayTypeIndex, PR_ALLOC_CLEAN);
|
| +
|
| +/* printf ("In NewArray a = %X \n", a); */
|
| +
|
| + if (a)
|
| + a->size = size;
|
| + return a;
|
| +}
|
| +
|
| +GCType arrayType = {
|
| + ScanArray,
|
| + FinalizeArray,
|
| + 0,
|
| + 0,
|
| + FreeArray,
|
| + 0
|
| +};
|
| +
|
| +static void Initialize(void)
|
| +{
|
| + PR_InitGC(0, 0, 0, PR_GLOBAL_THREAD);
|
| + arrayTypeIndex = PR_RegisterType(&arrayType);
|
| +}
|
| +
|
| +static void PR_CALLBACK AllocateLikeMad(void *arg)
|
| +{
|
| + Array *prev;
|
| + PRInt32 i;
|
| + PRInt32 count;
|
| +
|
| + count = (PRInt32)arg;
|
| + prev = 0;
|
| + for (i = 0; i < count; i++) {
|
| + Array *leak = NewArray(i & 511);
|
| + if ((i & 1023) == 0) {
|
| + prev = 0; /* forget */
|
| + } else {
|
| + if (i & 1) {
|
| + prev = leak; /* remember */
|
| + }
|
| + }
|
| + }
|
| + PR_EnterMonitor(mon);
|
| + waiting++;
|
| + PR_Notify(mon);
|
| + PR_ExitMonitor(mon);
|
| +}
|
| +
|
| +int main(int argc, char **argv)
|
| +{
|
| + PRIntervalTime start, stop, usec;
|
| + double d;
|
| + PRIntn i, totalIterations;
|
| + /* 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, "dt:c:");
|
| +
|
| + threads = 10;
|
| + iterations = 100;
|
| +
|
| + while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
|
| + {
|
| + if (PL_OPT_BAD == os) {
|
| + fprintf(stderr, "Invalid command-line option\n");
|
| + exit(1);
|
| + }
|
| + switch (opt->option)
|
| + {
|
| + case 'd': /* debug mode */
|
| + debug_mode = 1;
|
| + break;
|
| + case 't': /* number of threads */
|
| + threads = atoi(opt->value);
|
| + break;
|
| + case 'c': /* iteration count */
|
| + iterations = atoi(opt->value);
|
| + break;
|
| + default:
|
| + break;
|
| + }
|
| + }
|
| + PL_DestroyOptState(opt);
|
| +
|
| + fprintf(stderr, "t is %ld, i is %ld\n", (long) threads, (long) iterations);
|
| + /* main test */
|
| +
|
| + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 5);
|
| + PR_STDIO_INIT();
|
| + Initialize();
|
| +
|
| +#ifdef XP_MAC
|
| + SetupMacPrintfLog("gc1.log");
|
| + debug_mode = 1;
|
| +#endif
|
| +
|
| + /* Spin all of the allocator threads and then wait for them to exit */
|
| + start = PR_IntervalNow();
|
| + mon = PR_NewMonitor();
|
| + PR_EnterMonitor(mon);
|
| + waiting = 0;
|
| + for (i = 0; i < threads; i++) {
|
| + (void) PR_CreateThreadGCAble(PR_USER_THREAD,
|
| + AllocateLikeMad, (void*)iterations,
|
| + PR_PRIORITY_NORMAL,
|
| + PR_LOCAL_THREAD,
|
| + PR_UNJOINABLE_THREAD,
|
| + 0);
|
| + }
|
| + while (waiting != threads) {
|
| + PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
|
| + }
|
| + PR_ExitMonitor(mon);
|
| +
|
| + PR_GC();
|
| + PR_ForceFinalize();
|
| +
|
| + totalIterations = iterations * threads;
|
| +/*
|
| + if (scanCount != totalIterations)
|
| + printf ("scanCount discrepancy scanCount = %d totalIterations = %d \n",
|
| + scanCount, totalIterations);
|
| + if (freeCount != totalIterations)
|
| + printf ("freeCount discrepancy freeCount = %d totalIterations = %d \n",
|
| + freeCount, totalIterations);
|
| + if ((finalizeCount != totalIterations) && (finalizeCount != (totalIterations-1)))
|
| + printf ("finalizeCount discrepancy finalizeCount = %d totalIterations = %d \n",
|
| + finalizeCount,totalIterations);
|
| +*/
|
| +
|
| + stop = PR_IntervalNow();
|
| +
|
| + usec = stop = stop - start;
|
| + d = (double)usec;
|
| +
|
| + if (debug_mode) printf("%40s: %6.2f usec\n", "GC allocation", d / (iterations * threads));
|
| + else {
|
| + if (d == 0.0) failed_already = PR_TRUE;
|
| +
|
| + }
|
| +
|
| + PR_Cleanup();
|
| + if(failed_already)
|
| + {
|
| + printf("FAIL\n");
|
| + return 1;
|
| + }
|
| + else
|
| + {
|
| + printf("PASS\n");
|
| + return 0;
|
| + }
|
| +}
|
|
|