2011-01-07 Ivan Maidanski <ivmai@mail.ru>
authorivmai <ivmai>
Fri, 7 Jan 2011 09:51:40 +0000 (09:51 +0000)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 26 Jul 2011 17:06:55 +0000 (21:06 +0400)
* .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.

.cvsignore
ChangeLog
darwin_stop_world.c
include/private/.cvsignore
include/private/gcconfig.h
misc.c
os_dep.c
pthread_support.c

index 2b0e71a..d1ce9d2 100644 (file)
@@ -9,8 +9,9 @@ hugetest
 leaktest
 libcord.la
 libgc.la
+libstaticrootslib.la
 libtool
 middletest
 smashtest
+staticrootstest
 threadleaktest
-libstaticrootslib.la
index 193635e..fed5fa0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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"
index 5f15268..6af6918 100644 (file)
@@ -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, */
index f611548..fbe81bc 100644 (file)
@@ -1,2 +1,3 @@
 config.h
+config.h.in~
 stamp-h1
index 401d58b..653416f 100644 (file)
@@ -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.        */
 #       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__)
 #   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
 #       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
 #       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
 #       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
 #     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
 #       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
                  (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)
                             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);
     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 */
diff --git a/misc.c b/misc.c
index 7b38ee1..d350b73 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -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)
index b7f0fe9..17aec6f 100644 (file)
--- a/os_dep.c
+++ b/os_dep.c
@@ -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. */
index 26460a7..37e5d95 100644 (file)
@@ -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.                      */