diff options
author | wtc%netscape.com <devnull@localhost> | 1999-12-07 22:23:48 +0000 |
---|---|---|
committer | wtc%netscape.com <devnull@localhost> | 1999-12-07 22:23:48 +0000 |
commit | 350689b221fe4c2c78c068da002c36784327917c (patch) | |
tree | 083337834658bc671bc4b4204c3b2fb6df5def07 | |
parent | 57d033ba36eb40ba3c1290055c9d70cd1a1d5a35 (diff) | |
download | nspr-hg-350689b221fe4c2c78c068da002c36784327917c.tar.gz |
Reworked how thread scanning is done, so thread objects can now be
safely allocated on the thread stack. Moved the GC scanning code
into NSPR in a new file called prgcleak.c. (Checkin for Patrick Beard.)
Modified files: primpl.h, prinit.c, prthinfo.c, pruthr.c.
Added file: prgcleak.c.
-rw-r--r-- | pr/include/private/primpl.h | 3 | ||||
-rw-r--r-- | pr/src/md/mac/prgcleak.c | 99 | ||||
-rw-r--r-- | pr/src/misc/prinit.c | 4 | ||||
-rw-r--r-- | pr/src/misc/prthinfo.c | 13 | ||||
-rw-r--r-- | pr/src/threads/combined/pruthr.c | 13 |
5 files changed, 119 insertions, 13 deletions
diff --git a/pr/include/private/primpl.h b/pr/include/private/primpl.h index 8e461ddf..9cc3da5f 100644 --- a/pr/include/private/primpl.h +++ b/pr/include/private/primpl.h @@ -1606,6 +1606,9 @@ extern void _PR_CleanupTPD(void); extern void _PR_Cleanup(void); extern void _PR_LogCleanup(void); extern void _PR_InitLayerCache(void); +#ifdef GC_LEAK_DETECTOR +extern void _PR_InitGarbageCollector(void); +#endif extern PRBool _pr_initialized; extern void _PR_ImplicitInitialization(void); diff --git a/pr/src/md/mac/prgcleak.c b/pr/src/md/mac/prgcleak.c new file mode 100644 index 00000000..49b38b60 --- /dev/null +++ b/pr/src/md/mac/prgcleak.c @@ -0,0 +1,99 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public License + * Version 1.1 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1999 Netscape Communications Corporation. All Rights + * Reserved. + * + * Contributor(s): + * Patrick Beard <beard@netscape.com> + */ + +/* + * prgcleak.c + */ + +#ifdef GC_LEAK_DETECTOR + +/* for FILE */ +#include <stdio.h> + +/* NSPR stuff */ +#include "generic_threads.h" +#include "primpl.h" + +extern FILE *GC_stdout, *GC_stderr; + +extern void GC_gcollect(void); +extern void GC_clear_roots(void); + +static PRStatus PR_CALLBACK scanner(PRThread* t, void** baseAddr, PRUword +count, void* closure) +{ + char* begin = (char*)baseAddr; + char* end = (char*)(baseAddr + count); + GC_mark_range_proc marker = (GC_mark_range_proc) closure; + marker(begin, end); + return PR_SUCCESS; +} + +static void mark_all_stacks(GC_mark_range_proc marker) +{ + PR_ScanStackPointers(&scanner, (void *)marker); +} + +static void locker(void* mutex) +{ + if (_PR_MD_CURRENT_CPU()) + PR_Lock(mutex); +} + +static void unlocker(void* mutex) +{ + if (_PR_MD_CURRENT_CPU()) + PR_Unlock(mutex); +} + +static void stopper(void* unused) +{ + if (_PR_MD_CURRENT_CPU()) + PR_SuspendAll(); +} + +static void starter(void* unused) +{ + if (_PR_MD_CURRENT_CPU()) + PR_ResumeAll(); +} + +void _PR_InitGarbageCollector() +{ + void* mutex; + + /* redirect GC's stderr to catch startup leaks. */ + GC_stderr = fopen("StartupLeaks", "w"); + + mutex = PR_NewLock(); + PR_ASSERT(mutex != NULL); + + GC_generic_init_threads(&mark_all_stacks, mutex, + &locker, &unlocker, + &stopper, &starter); +} + +void _PR_ShutdownGarbageCollector() +{ + /* do anything you need to shut down the collector. */ +} + +#endif /* GC_LEAK_DETECTOR */ diff --git a/pr/src/misc/prinit.c b/pr/src/misc/prinit.c index 6c580443..8054228c 100644 --- a/pr/src/misc/prinit.c +++ b/pr/src/misc/prinit.c @@ -171,6 +171,10 @@ static void _PR_InitStuff(void) _pr_sleeplock = PR_NewLock(); PR_ASSERT(NULL != _pr_sleeplock); +#ifdef GC_LEAK_DETECTOR + _PR_InitGarbageCollector(); +#endif + _PR_InitThreads(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); #ifdef WIN16 diff --git a/pr/src/misc/prthinfo.c b/pr/src/misc/prthinfo.c index 67415420..2cfac1b2 100644 --- a/pr/src/misc/prthinfo.c +++ b/pr/src/misc/prthinfo.c @@ -140,6 +140,19 @@ PR_ThreadScanStackPointers(PRThread* t, if (status != PR_SUCCESS) return status; } + +#ifdef GC_LEAK_DETECTOR + /* + ** if the thread was allocated on its own stack, conservatively + ** scan the thread object itself to keep all data structures + ** referenced by the thread visible to the garbage collector. + */ + if (t->threadAllocatedOnStack) { + status = scanFun(t, (void**)t, (sizeof(PRThread) + 3) / sizeof(void*), scanClosure); + if (status != PR_SUCCESS) + return status; + } +#endif return PR_SUCCESS; } diff --git a/pr/src/threads/combined/pruthr.c b/pr/src/threads/combined/pruthr.c index 492ced6c..77d5a87b 100644 --- a/pr/src/threads/combined/pruthr.c +++ b/pr/src/threads/combined/pruthr.c @@ -1227,17 +1227,6 @@ PR_IMPLEMENT(PRThread*) _PR_CreateThread(PRThreadType type, return NULL; } -#if defined(GC_LEAK_DETECTOR) - top = stack->stackTop; - /* Allocate thread in heap, so GC will scan it. */ - thread = (PRThread*) PR_CALLOC(sizeof(PRThread)); - if (!thread) { - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; - } - stack->thr = thread; - thread->threadAllocatedOnStack = 0; -#else /* Allocate thread object and per-thread data off the top of the stack*/ top = stack->stackTop; #ifdef HAVE_STACK_GROWING_UP @@ -1262,8 +1251,6 @@ PR_IMPLEMENT(PRThread*) _PR_CreateThread(PRThreadType type, stack->thr = thread; memset(thread, 0, sizeof(PRThread)); thread->threadAllocatedOnStack = 1; -#endif - #else thread = _PR_MD_CREATE_USER_THREAD(stackSize, start, arg); if (!thread) { |