diff options
-rw-r--r-- | .cvsignore | 3 | ||||
-rw-r--r-- | ChangeLog | 32 | ||||
-rw-r--r-- | darwin_stop_world.c | 33 | ||||
-rw-r--r-- | include/private/.cvsignore | 1 | ||||
-rw-r--r-- | include/private/gcconfig.h | 41 | ||||
-rw-r--r-- | misc.c | 2 | ||||
-rw-r--r-- | os_dep.c | 185 | ||||
-rw-r--r-- | pthread_support.c | 205 |
8 files changed, 268 insertions, 234 deletions
@@ -9,8 +9,9 @@ hugetest leaktest libcord.la libgc.la +libstaticrootslib.la libtool middletest smashtest +staticrootstest threadleaktest -libstaticrootslib.la @@ -1,3 +1,35 @@ +2011-01-07 Ivan Maidanski <ivmai@mail.ru> + + * .cvsignore: Add more auto-generated files. + * include/private/.cvsignore: Ditto. + * darwin_stop_world.c (GC_mach_handler_thread, + GC_use_mach_handler_thread, + GC_darwin_register_mach_handler_thread): Define only if + MPROTECT_VDB. + * darwin_stop_world.c (GC_suspend_thread_list): Use + GC_mach_handler_thread and GC_use_mach_handler_thread only if + MPROTECT_VDB. + * darwin_stop_world.c (GC_stop_world): Reset GC_mach_threads_count + only if defined (i.e. unless GC_NO_THREADS_DISCOVERY). + * misc.c (GC_init): Fix comment for GWW_VDB. + * os_dep.c (GC_mprotect_state_t): Reformat the code. + * os_dep.c (DARWIN_EXC_STATE, DARWIN_EXC_STATE_COUNT, + DARWIN_EXC_STATE_T, DARWIN_EXC_STATE_DAR): New macros. + * os_dep.c (catch_exception_raise): Use DARWIN_EXC_STATE, + DARWIN_EXC_STATE_COUNT, DARWIN_EXC_STATE_T, DARWIN_EXC_STATE_DAR; + reformat the comment. + * pthread_support.c (GC_thr_init): Define "dummy" local variable + only unless GC_DARWIN_THREADS; reformat the code. + * include/private/gcconfig.h (MPROTECT_VDB): Define for Darwin + even in the single-threaded mode; define for iPhone/iPad. + * include/private/gcconfig.h (IA64): Remove unnecessary "ifdef" + around "undef". + * include/private/gcconfig.h (HEURISTIC1): Remove unused for + Cygwin. + * include/private/gcconfig.h (STACKBOTTOM): Use fixed address for + Darwin/arm (instead of HEURISTIC1). + * include/private/gcconfig.h (GET_MEM): Reformat the code. + 2011-01-05 Ivan Maidanski <ivmai@mail.ru> * misc.c (GC_write): Replace multiple "ifdef/endif" with "elif" diff --git a/darwin_stop_world.c b/darwin_stop_world.c index 5f152688..6af69184 100644 --- a/darwin_stop_world.c +++ b/darwin_stop_world.c @@ -328,14 +328,16 @@ GC_INNER void GC_push_all_stacks(void) #ifndef GC_NO_THREADS_DISCOVERY - STATIC mach_port_t GC_mach_handler_thread = 0; - STATIC GC_bool GC_use_mach_handler_thread = FALSE; +# ifdef MPROTECT_VDB + STATIC mach_port_t GC_mach_handler_thread = 0; + STATIC GC_bool GC_use_mach_handler_thread = FALSE; - GC_INNER void GC_darwin_register_mach_handler_thread(mach_port_t thread) - { - GC_mach_handler_thread = thread; - GC_use_mach_handler_thread = TRUE; - } + GC_INNER void GC_darwin_register_mach_handler_thread(mach_port_t thread) + { + GC_mach_handler_thread = thread; + GC_use_mach_handler_thread = TRUE; + } +# endif /* MPROTECT_VDB */ # ifndef GC_MAX_MACH_THREADS # define GC_MAX_MACH_THREADS THREAD_TABLE_SZ @@ -370,8 +372,11 @@ STATIC GC_bool GC_suspend_thread_list(thread_act_array_t act_list, int count, mach_msg_type_number_t outCount; kern_return_t kern_result; - if (thread == my_thread || (GC_mach_handler_thread == thread - && GC_use_mach_handler_thread)) { + if (thread == my_thread +# ifdef MPROTECT_VDB + || (GC_mach_handler_thread == thread && GC_use_mach_handler_thread) +# endif + ) { /* Don't add our and the handler threads. */ continue; } @@ -472,11 +477,6 @@ GC_INNER void GC_stop_world(void) GC_printf("Stopping the world from thread 0x%lx\n", (unsigned long)my_thread); # endif - /* Clear out the mach threads list table. We do not need to really */ - /* clear GC_mach_threads[] as it is used only in the range from 0 to */ - /* GC_mach_threads_count-1, inclusive. */ - GC_mach_threads_count = 0; - # ifdef PARALLEL_MARK if (GC_parallel) { /* Make sure all free list construction has stopped before we */ @@ -495,6 +495,11 @@ GC_INNER void GC_stop_world(void) thread_act_array_t act_list, prev_list; mach_msg_type_number_t listcount, prevcount; + /* Clear out the mach threads list table. We do not need to */ + /* really clear GC_mach_threads[] as it is used only in the range */ + /* from 0 to GC_mach_threads_count-1, inclusive. */ + GC_mach_threads_count = 0; + /* Loop stopping threads until you have gone over the whole list */ /* twice without a new one appearing. thread_create() won't */ /* return (and thus the thread stop) until the new thread exists, */ diff --git a/include/private/.cvsignore b/include/private/.cvsignore index f6115486..fbe81bc9 100644 --- a/include/private/.cvsignore +++ b/include/private/.cvsignore @@ -1,2 +1,3 @@ config.h +config.h.in~ stamp-h1 diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h index 401d58b7..653416fd 100644 --- a/include/private/gcconfig.h +++ b/include/private/gcconfig.h @@ -23,8 +23,7 @@ */ #ifndef GCCONFIG_H - -# define GCCONFIG_H +#define GCCONFIG_H # ifndef GC_PRIVATE_H /* Fake ptr_t declaration, just to avoid compilation errors. */ @@ -811,9 +810,7 @@ # define USE_MMAP # endif # define USE_MMAP_ANON -# ifdef GC_DARWIN_THREADS -# define MPROTECT_VDB -# endif +# define MPROTECT_VDB # include <unistd.h> # define GETPAGESIZE() getpagesize() # if defined(USE_PPC_PREFETCH) && defined(__GNUC__) @@ -888,11 +885,9 @@ # ifdef AIX # define OS_TYPE "AIX" # undef ALIGNMENT /* in case it's defined */ -# ifdef IA64 -# undef IA64 - /* DOB: some AIX installs stupidly define IA64 in */ - /* /usr/include/sys/systemcfg.h */ -# endif +# undef IA64 + /* DOB: some AIX installs stupidly define IA64 in */ + /* /usr/include/sys/systemcfg.h */ # ifdef __64BIT__ # define ALIGNMENT 8 # define CPP_WORDSZ 64 @@ -1163,9 +1158,9 @@ # define MAP_FAILED (void *) ((word)-1) # ifdef USE_MMAP # define HEAP_START (ptr_t)0x40000000 -# else /* USE_MMAP */ +# else # define HEAP_START DATAEND -# endif /* USE_MMAP */ +# endif # endif /* DGUX */ # ifdef LINUX @@ -1247,7 +1242,6 @@ # define DATAEND ((ptr_t)GC_DATAEND) # undef STACK_GRAN # define STACK_GRAN 0x10000 -# define HEURISTIC1 # ifdef USE_MMAP # define NEED_FIND_LIMIT # define USE_MMAP_ANON @@ -1384,9 +1378,7 @@ # define USE_MMAP # endif # define USE_MMAP_ANON -# ifdef GC_DARWIN_THREADS -# define MPROTECT_VDB -# endif +# define MPROTECT_VDB # include <unistd.h> # define GETPAGESIZE() getpagesize() /* There seems to be some issues with trylock hanging on darwin. This @@ -1900,12 +1892,12 @@ # define OS_TYPE "DARWIN" # define DATASTART ((ptr_t) get_etext()) # define DATAEND ((ptr_t) get_end()) -/* #define STACKBOTTOM ((ptr_t) 0x30000000) */ /* FIXME: Is this needed? */ -# define HEURISTIC1 +# define STACKBOTTOM ((ptr_t) 0x30000000) # ifndef USE_MMAP # define USE_MMAP # endif # define USE_MMAP_ANON +# define MPROTECT_VDB # endif # ifdef OPENBSD # define ALIGNMENT 4 @@ -2085,9 +2077,7 @@ # define USE_MMAP # endif # define USE_MMAP_ANON -# ifdef GC_DARWIN_THREADS -# define MPROTECT_VDB -# endif +# define MPROTECT_VDB # include <unistd.h> # define GETPAGESIZE() getpagesize() /* There seems to be some issues with trylock hanging on darwin. This @@ -2609,7 +2599,7 @@ (defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) || \ (defined(SOLARIS) && !defined(USE_MMAP)) # define GET_MEM(bytes) HBLKPTR((size_t) calloc(1, (size_t)bytes + GC_page_size) \ - + GC_page_size-1) + + GC_page_size-1) # elif defined(MSWIN32) || defined(CYGWIN32) ptr_t GC_win32_get_mem(GC_word bytes); # define GET_MEM(bytes) (struct hblk *)GC_win32_get_mem(bytes) @@ -2620,8 +2610,8 @@ GC_MacTemporaryNewPtr(bytes + GC_page_size, true) \ + GC_page_size-1) # else -# define GET_MEM(bytes) HBLKPTR( \ - NewPtrClear(bytes + GC_page_size) + GC_page_size-1) +# define GET_MEM(bytes) HBLKPTR(NewPtrClear(bytes + GC_page_size) \ + + GC_page_size-1) # endif # elif defined(MSWINCE) ptr_t GC_wince_get_mem(GC_word bytes); @@ -2638,7 +2628,6 @@ ptr_t GC_unix_get_mem(GC_word bytes); # define GET_MEM(bytes) (struct hblk *)GC_unix_get_mem(bytes) # endif - #endif /* GC_PRIVATE_H */ -# endif /* GCCONFIG_H */ +#endif /* GCCONFIG_H */ @@ -891,7 +891,7 @@ GC_API void GC_CALL GC_init(void) GC_STATIC_ASSERT((signed_word)(-1) < (signed_word)0); # ifndef GC_DISABLE_INCREMENTAL if (GC_incremental || 0 != GETENV("GC_ENABLE_INCREMENTAL")) { - /* For GWW_MPROTECT on Win32, this needs to happen before any */ + /* For GWW_VDB on Win32, this needs to happen before any */ /* heap memory is allocated. */ GC_dirty_init(); GC_ASSERT(GC_bytes_allocd == 0) @@ -3334,12 +3334,11 @@ GC_API int GC_CALL GC_incremental_protection_needs(void) return GC_PROTECTS_POINTER_HEAP | GC_PROTECTS_PTRFREE_HEAP; } } - #define HAVE_INCREMENTAL_PROTECTION_NEEDS #define IS_PTRFREE(hhdr) ((hhdr)->hb_descr == 0) - #define PAGE_ALIGNED(x) !((word)(x) & (GC_page_size - 1)) + STATIC void GC_protect_heap(void) { ptr_t start; @@ -3849,7 +3848,9 @@ typedef struct { } GC_msg_t; typedef enum { - GC_MP_NORMAL, GC_MP_DISCARDING, GC_MP_STOPPED + GC_MP_NORMAL, + GC_MP_DISCARDING, + GC_MP_STOPPED } GC_mprotect_state_t; /* FIXME: 1 and 2 seem to be safe to use in the msgh_id field, @@ -4182,8 +4183,40 @@ STATIC kern_return_t GC_forward_exception(mach_port_t thread, mach_port_t task, #define FWD() GC_forward_exception(thread, task, exception, code, code_count) -/* This violates the namespace rules but there isn't anything that can be done - about it. The exception handling stuff is hard coded to call this. */ +#ifdef ARM32 +# define DARWIN_EXC_STATE ARM_EXCEPTION_STATE +# define DARWIN_EXC_STATE_COUNT ARM_EXCEPTION_STATE_COUNT +# define DARWIN_EXC_STATE_T arm_exception_state_t +# define DARWIN_EXC_STATE_DAR THREAD_FLD(far) +#elif defined(POWERPC) +# if CPP_WORDSZ == 32 +# define DARWIN_EXC_STATE PPC_EXCEPTION_STATE +# define DARWIN_EXC_STATE_COUNT PPC_EXCEPTION_STATE_COUNT +# define DARWIN_EXC_STATE_T ppc_exception_state_t +# else +# define DARWIN_EXC_STATE PPC_EXCEPTION_STATE64 +# define DARWIN_EXC_STATE_COUNT PPC_EXCEPTION_STATE64_COUNT +# define DARWIN_EXC_STATE_T ppc_exception_state64_t +# endif +# define DARWIN_EXC_STATE_DAR THREAD_FLD(dar) +#elif defined(I386) || defined(X86_64) +# if CPP_WORDSZ == 32 +# define DARWIN_EXC_STATE x86_EXCEPTION_STATE32 +# define DARWIN_EXC_STATE_COUNT x86_EXCEPTION_STATE32_COUNT +# define DARWIN_EXC_STATE_T x86_exception_state32_t +# else +# define DARWIN_EXC_STATE x86_EXCEPTION_STATE64 +# define DARWIN_EXC_STATE_COUNT x86_EXCEPTION_STATE64_COUNT +# define DARWIN_EXC_STATE_T x86_exception_state64_t +# endif +# define DARWIN_EXC_STATE_DAR THREAD_FLD(faultvaddr) +#else +# error FIXME for non-arm/ppc/x86 darwin +#endif + +/* This violates the namespace rules but there isn't anything that can */ +/* be done about it. The exception handling stuff is hard coded to */ +/* call this. */ kern_return_t catch_exception_raise(mach_port_t exception_port, mach_port_t thread, mach_port_t task, exception_type_t exception, @@ -4193,30 +4226,9 @@ catch_exception_raise(mach_port_t exception_port, mach_port_t thread, char *addr; struct hblk *h; unsigned int i; -# if defined(POWERPC) -# if CPP_WORDSZ == 32 - thread_state_flavor_t flavor = PPC_EXCEPTION_STATE; - mach_msg_type_number_t exc_state_count = PPC_EXCEPTION_STATE_COUNT; - ppc_exception_state_t exc_state; -# else - thread_state_flavor_t flavor = PPC_EXCEPTION_STATE64; - mach_msg_type_number_t exc_state_count = PPC_EXCEPTION_STATE64_COUNT; - ppc_exception_state64_t exc_state; -# endif -# elif defined(I386) || defined(X86_64) -# if CPP_WORDSZ == 32 - thread_state_flavor_t flavor = x86_EXCEPTION_STATE32; - mach_msg_type_number_t exc_state_count = x86_EXCEPTION_STATE32_COUNT; - x86_exception_state32_t exc_state; -# else - thread_state_flavor_t flavor = x86_EXCEPTION_STATE64; - mach_msg_type_number_t exc_state_count = x86_EXCEPTION_STATE64_COUNT; - x86_exception_state64_t exc_state; -# endif -# else -# error FIXME for non-ppc/x86 darwin -# endif - + thread_state_flavor_t flavor = DARWIN_EXC_STATE; + mach_msg_type_number_t exc_state_count = DARWIN_EXC_STATE_COUNT; + DARWIN_EXC_STATE_T exc_state; if(exception != EXC_BAD_ACCESS || code[0] != KERN_PROTECTION_FAILURE) { # ifdef DEBUG_EXCEPTION_HANDLING @@ -4240,70 +4252,63 @@ catch_exception_raise(mach_port_t exception_port, mach_port_t thread, # endif } - /* This is the address that caused the fault */ -# if defined(POWERPC) - addr = (char*) exc_state. THREAD_FLD(dar); -# elif defined (I386) || defined (X86_64) - addr = (char*) exc_state. THREAD_FLD(faultvaddr); -# else -# error FIXME for non POWERPC/I386 -# endif - - if((HDR(addr)) == 0) { - /* Ugh... just like the SIGBUS problem above, it seems we get a bogus - KERN_PROTECTION_FAILURE every once and a while. We wait till we get - a bunch in a row before doing anything about it. If a "real" fault - ever occurs it'll just keep faulting over and over and we'll hit - the limit pretty quickly. */ -# ifdef BROKEN_EXCEPTION_HANDLING - static char *last_fault; - static int last_fault_count; - - if(addr != last_fault) { - last_fault = addr; - last_fault_count = 0; - } - if(++last_fault_count < 32) { - if(last_fault_count == 1) - WARN("Ignoring KERN_PROTECTION_FAILURE at %p\n", addr); - return KERN_SUCCESS; - } - - GC_err_printf("Unexpected KERN_PROTECTION_FAILURE at %p\n" - "Aborting...\n", addr); - /* Can't pass it along to the signal handler because that is - ignoring SIGBUS signals. We also shouldn't call ABORT here as - signals don't always work too well from the exception handler. */ - exit(EXIT_FAILURE); -# else /* BROKEN_EXCEPTION_HANDLING */ - /* Pass it along to the next exception handler - (which should call SIGBUS/SIGSEGV) */ - return FWD(); -# endif /* !BROKEN_EXCEPTION_HANDLING */ - } - + /* This is the address that caused the fault */ + addr = (char*) exc_state.DARWIN_EXC_STATE_DAR; + if ((HDR(addr)) == 0) { + /* Ugh... just like the SIGBUS problem above, it seems we get a bogus + KERN_PROTECTION_FAILURE every once and a while. We wait till we get + a bunch in a row before doing anything about it. If a "real" fault + ever occurs it'll just keep faulting over and over and we'll hit + the limit pretty quickly. */ # ifdef BROKEN_EXCEPTION_HANDLING - /* Reset the number of consecutive SIGBUSs */ - GC_sigbus_count = 0; -# endif + static char *last_fault; + static int last_fault_count; - if(GC_mprotect_state == GC_MP_NORMAL) { /* common case */ - h = (struct hblk*)((word)addr & ~(GC_page_size-1)); - UNPROTECT(h, GC_page_size); - for (i = 0; i < divHBLKSZ(GC_page_size); i++) { - register int index = PHT_HASH(h+i); - async_set_pht_entry_from_index(GC_dirty_pages, index); + if(addr != last_fault) { + last_fault = addr; + last_fault_count = 0; } - } else if(GC_mprotect_state == GC_MP_DISCARDING) { - /* Lie to the thread for now. No sense UNPROTECT()ing the memory - when we're just going to PROTECT() it again later. The thread - will just fault again once it resumes */ - } else { - /* Shouldn't happen, i don't think */ - GC_err_printf("KERN_PROTECTION_FAILURE while world is stopped\n"); + if(++last_fault_count < 32) { + if(last_fault_count == 1) + WARN("Ignoring KERN_PROTECTION_FAILURE at %p\n", addr); + return KERN_SUCCESS; + } + + GC_err_printf("Unexpected KERN_PROTECTION_FAILURE at %p\n" + "Aborting...\n", addr); + /* Can't pass it along to the signal handler because that is + ignoring SIGBUS signals. We also shouldn't call ABORT here as + signals don't always work too well from the exception handler. */ + exit(EXIT_FAILURE); +# else /* BROKEN_EXCEPTION_HANDLING */ + /* Pass it along to the next exception handler + (which should call SIGBUS/SIGSEGV) */ return FWD(); +# endif /* !BROKEN_EXCEPTION_HANDLING */ + } + +# ifdef BROKEN_EXCEPTION_HANDLING + /* Reset the number of consecutive SIGBUSs */ + GC_sigbus_count = 0; +# endif + + if(GC_mprotect_state == GC_MP_NORMAL) { /* common case */ + h = (struct hblk*)((word)addr & ~(GC_page_size-1)); + UNPROTECT(h, GC_page_size); + for (i = 0; i < divHBLKSZ(GC_page_size); i++) { + register int index = PHT_HASH(h+i); + async_set_pht_entry_from_index(GC_dirty_pages, index); } - return KERN_SUCCESS; + } else if(GC_mprotect_state == GC_MP_DISCARDING) { + /* Lie to the thread for now. No sense UNPROTECT()ing the memory + when we're just going to PROTECT() it again later. The thread + will just fault again once it resumes */ + } else { + /* Shouldn't happen, i don't think */ + GC_err_printf("KERN_PROTECTION_FAILURE while world is stopped\n"); + return FWD(); + } + return KERN_SUCCESS; } #undef FWD @@ -4333,12 +4338,12 @@ catch_exception_raise_state_identity(mach_port_name_t exception_port, #endif /* DARWIN && MPROTECT_VDB */ -# ifndef HAVE_INCREMENTAL_PROTECTION_NEEDS +#ifndef HAVE_INCREMENTAL_PROTECTION_NEEDS GC_API int GC_CALL GC_incremental_protection_needs(void) { return GC_PROTECTS_NONE; } -# endif /* !HAVE_INCREMENTAL_PROTECTION_NEEDS */ +#endif /* !HAVE_INCREMENTAL_PROTECTION_NEEDS */ #ifdef ECOS /* Undo sbrk() redirection. */ diff --git a/pthread_support.c b/pthread_support.c index 26460a79..37e5d95f 100644 --- a/pthread_support.c +++ b/pthread_support.c @@ -856,119 +856,120 @@ STATIC void GC_fork_child_proc(void) /* We hold the allocation lock. */ GC_INNER void GC_thr_init(void) { +# ifndef GC_DARWIN_THREADS int dummy; +# endif + if (GC_thr_initialized) return; + GC_thr_initialized = TRUE; - if (GC_thr_initialized) return; - GC_thr_initialized = TRUE; - -# ifdef HANDLE_FORK - /* Prepare for a possible fork. */ - pthread_atfork(GC_fork_prepare_proc, GC_fork_parent_proc, - GC_fork_child_proc); -# endif /* HANDLE_FORK */ -# if defined(INCLUDE_LINUX_THREAD_DESCR) - /* Explicitly register the region including the address */ - /* of a thread local variable. This should include thread */ - /* locals for the main thread, except for those allocated */ - /* in response to dlopen calls. */ - { - ptr_t thread_local_addr = (ptr_t)(&GC_dummy_thread_local); - ptr_t main_thread_start, main_thread_end; - if (!GC_enclosing_mapping(thread_local_addr, &main_thread_start, - &main_thread_end)) { - ABORT("Failed to find mapping for main thread thread locals"); - } - GC_add_roots_inner(main_thread_start, main_thread_end, FALSE); - } -# endif - /* Add the initial thread, so we can stop it. */ +# ifdef HANDLE_FORK + /* Prepare for a possible fork. */ + pthread_atfork(GC_fork_prepare_proc, GC_fork_parent_proc, + GC_fork_child_proc); +# endif +# ifdef INCLUDE_LINUX_THREAD_DESCR + /* Explicitly register the region including the address */ + /* of a thread local variable. This should include thread */ + /* locals for the main thread, except for those allocated */ + /* in response to dlopen calls. */ { - GC_thread t = GC_new_thread(pthread_self()); -# ifdef GC_DARWIN_THREADS - t -> stop_info.mach_thread = mach_thread_self(); -# else - t -> stop_info.stack_ptr = (ptr_t)(&dummy); -# endif - t -> flags = DETACHED | MAIN_THREAD; + ptr_t thread_local_addr = (ptr_t)(&GC_dummy_thread_local); + ptr_t main_thread_start, main_thread_end; + if (!GC_enclosing_mapping(thread_local_addr, &main_thread_start, + &main_thread_end)) { + ABORT("Failed to find mapping for main thread thread locals"); + } + GC_add_roots_inner(main_thread_start, main_thread_end, FALSE); } - -# ifndef GC_DARWIN_THREADS - GC_stop_init(); +# endif + /* Add the initial thread, so we can stop it. */ + { + GC_thread t = GC_new_thread(pthread_self()); +# ifdef GC_DARWIN_THREADS + t -> stop_info.mach_thread = mach_thread_self(); +# else + t -> stop_info.stack_ptr = (ptr_t)(&dummy); # endif + t -> flags = DETACHED | MAIN_THREAD; + } - /* Set GC_nprocs. */ - { - char * nprocs_string = GETENV("GC_NPROCS"); - GC_nprocs = -1; - if (nprocs_string != NULL) GC_nprocs = atoi(nprocs_string); - } - if (GC_nprocs <= 0) { -# if defined(GC_HPUX_THREADS) - GC_nprocs = pthread_num_processors_np(); -# endif -# if defined(GC_OSF1_THREADS) || defined(GC_AIX_THREADS) \ - || defined(GC_SOLARIS_THREADS) || defined(GC_GNU_THREADS) - GC_nprocs = sysconf(_SC_NPROCESSORS_ONLN); - if (GC_nprocs <= 0) GC_nprocs = 1; -# endif -# if defined(GC_IRIX_THREADS) - GC_nprocs = sysconf(_SC_NPROC_ONLN); - if (GC_nprocs <= 0) GC_nprocs = 1; -# endif -# if defined(GC_DARWIN_THREADS) || defined(GC_FREEBSD_THREADS) \ - || defined(GC_NETBSD_THREADS) || defined(GC_OPENBSD_THREADS) - GC_nprocs = get_ncpu(); -# endif -# if defined(GC_LINUX_THREADS) || defined(GC_DGUX386_THREADS) - GC_nprocs = GC_get_nprocs(); -# endif - } - if (GC_nprocs <= 0) { - WARN("GC_get_nprocs() returned %" GC_PRIdPTR "\n", GC_nprocs); - GC_nprocs = 2; -# ifdef PARALLEL_MARK - GC_markers = 1; -# endif - } else { -# ifdef PARALLEL_MARK - { - char * markers_string = GETENV("GC_MARKERS"); - if (markers_string != NULL) { - GC_markers = atoi(markers_string); - if (GC_markers > MAX_MARKERS) { - WARN("Limiting number of mark threads\n", 0); - GC_markers = MAX_MARKERS; - } - } else { - GC_markers = GC_nprocs; - if (GC_markers >= MAX_MARKERS) - GC_markers = MAX_MARKERS; /* silently limit GC_markers value */ - } - } -# endif - } +# ifndef GC_DARWIN_THREADS + GC_stop_init(); +# endif + + /* Set GC_nprocs. */ + { + char * nprocs_string = GETENV("GC_NPROCS"); + GC_nprocs = -1; + if (nprocs_string != NULL) GC_nprocs = atoi(nprocs_string); + } + if (GC_nprocs <= 0) { +# if defined(GC_HPUX_THREADS) + GC_nprocs = pthread_num_processors_np(); +# endif +# if defined(GC_OSF1_THREADS) || defined(GC_AIX_THREADS) \ + || defined(GC_SOLARIS_THREADS) || defined(GC_GNU_THREADS) + GC_nprocs = sysconf(_SC_NPROCESSORS_ONLN); + if (GC_nprocs <= 0) GC_nprocs = 1; +# endif +# if defined(GC_IRIX_THREADS) + GC_nprocs = sysconf(_SC_NPROC_ONLN); + if (GC_nprocs <= 0) GC_nprocs = 1; +# endif +# if defined(GC_DARWIN_THREADS) || defined(GC_FREEBSD_THREADS) \ + || defined(GC_NETBSD_THREADS) || defined(GC_OPENBSD_THREADS) + GC_nprocs = get_ncpu(); +# endif +# if defined(GC_LINUX_THREADS) || defined(GC_DGUX386_THREADS) + GC_nprocs = GC_get_nprocs(); +# endif + } + if (GC_nprocs <= 0) { + WARN("GC_get_nprocs() returned %" GC_PRIdPTR "\n", GC_nprocs); + GC_nprocs = 2; # ifdef PARALLEL_MARK + GC_markers = 1; +# endif + } else { +# ifdef PARALLEL_MARK + { + char * markers_string = GETENV("GC_MARKERS"); + if (markers_string != NULL) { + GC_markers = atoi(markers_string); + if (GC_markers > MAX_MARKERS) { + WARN("Limiting number of mark threads\n", 0); + GC_markers = MAX_MARKERS; + } + } else { + GC_markers = GC_nprocs; + if (GC_markers >= MAX_MARKERS) + GC_markers = MAX_MARKERS; /* silently limit GC_markers value */ + } + } +# endif + } +# ifdef PARALLEL_MARK + if (GC_print_stats) { + GC_log_printf("Number of processors = %ld, " + "number of marker threads = %ld\n", GC_nprocs, GC_markers); + } + if (GC_markers <= 1) { + GC_parallel = FALSE; if (GC_print_stats) { - GC_log_printf("Number of processors = %ld, " - "number of marker threads = %ld\n", GC_nprocs, GC_markers); - } - if (GC_markers <= 1) { - GC_parallel = FALSE; - if (GC_print_stats) { - GC_log_printf( - "Single marker thread, turning off parallel marking\n"); - } - } else { - GC_parallel = TRUE; - /* Disable true incremental collection, but generational is OK. */ - GC_time_limit = GC_TIME_UNLIMITED; + GC_log_printf("Single marker thread, turning off parallel marking\n"); } - /* If we are using a parallel marker, actually start helper threads. */ - if (GC_parallel) start_mark_threads(); -# endif + } else { + GC_parallel = TRUE; + /* Disable true incremental collection, but generational is OK. */ + GC_time_limit = GC_TIME_UNLIMITED; + } + /* If we are using a parallel marker, actually start helper threads. */ + if (GC_parallel) { + start_mark_threads(); + } +# endif } - /* Perform all initializations, including those that */ /* may require allocation. */ /* Called without allocation lock. */ |