* src/boehm-gc/darwin_stop_world.c,
authortwisti <none@none>
Mon, 20 Mar 2006 14:27:47 +0000 (14:27 +0000)
committertwisti <none@none>
Mon, 20 Mar 2006 14:27:47 +0000 (14:27 +0000)
src/boehm-gc/threadlibs.c,
src/boehm-gc/doc/README.changes,
src/boehm-gc/doc/README,
src/boehm-gc/doc/gcinterface.html,
src/boehm-gc/mark.c,
src/boehm-gc/include/gc.h,
src/boehm-gc/include/gc_cpp.h,
src/boehm-gc/include/gc_pthread_redirects.h,
src/boehm-gc/include/leak_detector.h,
src/boehm-gc/include/gc_config_macros.h,
src/boehm-gc/include/private/gc_priv.h,
src/boehm-gc/include/private/gcconfig.h,
src/boehm-gc/include/private/gc_pmark.h,
src/boehm-gc/include/private/gc_locks.h,
src/boehm-gc/configure.in,
src/boehm-gc/allchblk.c,
src/boehm-gc/powerpc_darwin_mach_dep.s,
src/boehm-gc/dbg_mlc.c,
src/boehm-gc/version.h,
src/boehm-gc/pthread_stop_world.c,
src/boehm-gc/malloc.c,
src/boehm-gc/headers.c,
src/boehm-gc/pthread_support.c,
src/boehm-gc/Makefile.direct,
src/boehm-gc/os_dep.c,
src/boehm-gc/Makefile.am,
src/boehm-gc/dyn_load.c,
src/boehm-gc/alloc.c,
src/boehm-gc/misc.c: Updated to upstream version 6.7.

30 files changed:
src/boehm-gc/Makefile.am
src/boehm-gc/Makefile.direct
src/boehm-gc/allchblk.c
src/boehm-gc/alloc.c
src/boehm-gc/configure.in
src/boehm-gc/darwin_stop_world.c
src/boehm-gc/dbg_mlc.c
src/boehm-gc/doc/README
src/boehm-gc/doc/README.changes
src/boehm-gc/doc/gcinterface.html
src/boehm-gc/dyn_load.c
src/boehm-gc/headers.c
src/boehm-gc/include/gc.h
src/boehm-gc/include/gc_config_macros.h
src/boehm-gc/include/gc_cpp.h
src/boehm-gc/include/gc_pthread_redirects.h
src/boehm-gc/include/leak_detector.h
src/boehm-gc/include/private/gc_locks.h
src/boehm-gc/include/private/gc_pmark.h
src/boehm-gc/include/private/gc_priv.h
src/boehm-gc/include/private/gcconfig.h
src/boehm-gc/malloc.c
src/boehm-gc/mark.c
src/boehm-gc/misc.c
src/boehm-gc/os_dep.c
src/boehm-gc/powerpc_darwin_mach_dep.s
src/boehm-gc/pthread_stop_world.c
src/boehm-gc/pthread_support.c
src/boehm-gc/threadlibs.c
src/boehm-gc/version.h

index a663e810b7ca016375d700277c97078dab4ba7af..36a55587c8b48f02362ea2be5d6f9b106c511ab0 100644 (file)
@@ -95,7 +95,7 @@ test_cpp.o:   $(srcdir)/tests/test_cpp.cc
 #test_cpp_SOURCES = tests/test_cpp.cc
 #test_cpp_LDADD = ./libgc.la ./libgccpp.la $(THREADDLLIBS) $(UNWINDLIBS) $(EXTRA_TEST_LIBS)
 
-#TESTS = gctest $(extra_checks)
+TESTS = $(check_PROGRAMS)
 
 ## FIXME: relies on internal code generated by automake.
 all_objs = @addobjs@ $(libgc_la_OBJECTS)
index 1f03b511c3b298c6fc71abcdbfc3bc2d090d944e..462a54fe70914cf17611eef3f14c83844ac8da34 100644 (file)
@@ -144,9 +144,9 @@ HOSTCFLAGS=$(CFLAGS)
 # -DJAVA_FINALIZATION makes it somewhat safer to finalize objects out of
 #   order by specifying a nonstandard finalization mark procedure  (see
 #   finalize.c).  Objects reachable from finalizable objects will be marked
-#   in a sepearte postpass, and hence their memory won't be reclaimed.
+#   in a separate postpass, and hence their memory won't be reclaimed.
 #   Not recommended unless you are implementing a language that specifies
-#   these semantics.  Since 5.0, determines only only the initial value
+#   these semantics.  Since 5.0, determines only the initial value
 #   of GC_java_finalization variable.
 # -DFINALIZE_ON_DEMAND causes finalizers to be run only in response
 #   to explicit GC_invoke_finalizers() calls.
index 7028ef301abe45ba51438148decf59b168637260..aec95dd11d559b5b4977f2caf369fe1d60ca404a 100644 (file)
@@ -531,7 +531,7 @@ int index;  /* Index of free list */
                                /* free blocks in GC_add_to_fl.         */
 #     endif
 #   ifdef USE_MUNMAP
-      hhdr -> hb_last_reclaimed = GC_gc_no;
+      hhdr -> hb_last_reclaimed = (unsigned short)GC_gc_no;
 #   endif
     hhdr -> hb_sz = h_size;
     GC_add_to_fl(h, hhdr);
@@ -795,7 +795,7 @@ signed_word size;
     GC_remove_counts(hbp, (word)size);
     hhdr->hb_sz = size;
 #   ifdef USE_MUNMAP
-      hhdr -> hb_last_reclaimed = GC_gc_no;
+      hhdr -> hb_last_reclaimed = (unsigned short)GC_gc_no;
 #   endif
     
     /* Check for duplicate deallocation in the easy case */
@@ -823,7 +823,7 @@ signed_word size;
          GC_remove_from_fl(prevhdr, FL_UNKNOWN);
          prevhdr -> hb_sz += hhdr -> hb_sz;
 #        ifdef USE_MUNMAP
-           prevhdr -> hb_last_reclaimed = GC_gc_no;
+           prevhdr -> hb_last_reclaimed = (unsigned short)GC_gc_no;
 #        endif
          GC_remove_header(hbp);
          hbp = prev;
index 8a2a44e68b38e3747331b47a2dbd050529905e39..5cd25cc03058d512ec38140cd7dac832ca93065c 100644 (file)
@@ -207,7 +207,7 @@ word GC_adj_words_allocd()
        /* had been reallocated this round. Finalization is user        */
        /* visible progress.  And if we don't count this, we have       */
        /* stability problems for programs that finalize all objects.   */
-    if ((GC_words_wasted >> 3) < result)
+    if ((signed_word)(GC_words_wasted >> 3) < result)
         result += GC_words_wasted;
        /* This doesn't reflect useful work.  But if there is lots of   */
        /* new fragmentation, the same is probably true of the heap,    */
@@ -403,7 +403,7 @@ GC_stop_func stop_func;
 /*
  * Perform n units of garbage collection work.  A unit is intended to touch
  * roughly GC_RATE pages.  Every once in a while, we do more than that.
- * This needa to be a fairly large number with our current incremental
+ * This needs to be a fairly large number with our current incremental
  * GC strategy, since otherwise we allocate too much during GC, and the
  * cleanup gets expensive.
  */
index d6fc006e1e581c64daa9ec00da87f638bed94d5f..fc5b2a267956b070f9025e4ce029dbec45cdb1b2 100644 (file)
@@ -17,12 +17,12 @@ dnl Process this file with autoconf to produce configure.
 # Initialization
 # ==============
 
-AC_INIT(gc,6.6,Hans.Boehm@hp.com) 
+AC_INIT(gc,6.7,Hans.Boehm@hp.com) 
     ## version must conform to [0-9]+[.][0-9]+(alpha[0-9]+)?
 AC_CONFIG_SRCDIR(gcj_mlc.c)
 AC_CANONICAL_TARGET 
 AC_PREREQ(2.53)
-AC_REVISION($Revision: 3439 $)
+AC_REVISION($Revision: 4655 $)
 GC_SET_VERSION
 AM_INIT_AUTOMAKE
 
@@ -115,6 +115,13 @@ case "$THREADS" in
        INCLUDES="$INCLUDES -pthread"
        THREADDLLIBS=-pthread
        ;;
+     *-*-netbsd*)
+       AC_MSG_WARN("Only on NetBSD 2.0 or later.")
+       AC_DEFINE([GC_NETBSD_THREADS], 1, [GC NetBSD threads])
+       AC_DEFINE([_REENTRANT], 1, [reentrant])
+       AC_DEFINE([_PTHREADS], 1, [pthreads])
+       THREADDLLIBS="-lpthread -lrt"
+       ;;
      *-*-solaris*)
        AC_DEFINE([GC_SOLARIS_THREADS], 1, [gc solaris threads])
        AC_DEFINE([GC_SOLARIS_PTHREADS], 1, [gc solaris pthreads])
index f0c6452bb760ccae0dd264eeaaa74aae56bb4a14..894bd051e66904ca71e8fbacf6d7eb04b821aaca 100644 (file)
@@ -2,6 +2,8 @@
 
 #include "private/pthread_support.h"
 
+/* This probably needs more porting work to ppc64. */
+
 # if defined(GC_DARWIN_THREADS)
 
 /* From "Inside Mac OS X - Mach-O Runtime Architecture" published by Apple
@@ -38,7 +40,7 @@ unsigned long FindTopOfStack(unsigned int stack_start) {
 #   if CPP_WORDSZ == 32
       __asm__ volatile("lwz    %0,0(r1)" : "=r" (frame));
 #   else
-      __asm__ volatile("ldz    %0,0(r1)" : "=r" (frame));
+      __asm__ volatile("ld     %0,0(r1)" : "=r" (frame));
 #   endif
 # endif
   } else {
@@ -75,7 +77,13 @@ void GC_push_all_stacks() {
   GC_thread p;
   pthread_t me;
   ptr_t lo, hi;
+#if defined(POWERPC)
   ppc_thread_state_t state;
+#elif defined(I386)
+  i386_thread_state_t state;
+#else
+# error FIXME for non-x86 || ppc architectures
+#endif
   mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
   
   me = pthread_self();
@@ -95,6 +103,17 @@ void GC_push_all_stacks() {
                             &thread_state_count);
        if(r != KERN_SUCCESS) ABORT("thread_get_state failed");
        
+#if defined(I386)
+       lo = state.esp;
+
+       GC_push_one(state.eax); 
+       GC_push_one(state.ebx); 
+       GC_push_one(state.ecx); 
+       GC_push_one(state.edx); 
+       GC_push_one(state.edi); 
+       GC_push_one(state.esi); 
+       GC_push_one(state.ebp); 
+#elif defined(POWERPC)
        lo = (void*)(state.r1 - PPC_RED_ZONE_SIZE);
         
        GC_push_one(state.r0); 
@@ -128,6 +147,9 @@ void GC_push_all_stacks() {
        GC_push_one(state.r29); 
        GC_push_one(state.r30); 
        GC_push_one(state.r31);
+#else
+# error FIXME for non-x86 || ppc architectures
+#endif
       } /* p != me */
       if(p->flags & MAIN_THREAD)
        hi = GC_stackbottom;
@@ -249,6 +271,7 @@ void GC_push_all_stacks() {
 #     endif
       GC_push_all_stack(lo, hi); 
     } /* for(p=GC_threads[i]...) */
+    vm_deallocate(current_task(), (vm_address_t)act_list, sizeof(thread_t) * listcount);
 }
 #endif /* !DARWIN_DONT_PARSE_STACK */
 
@@ -392,6 +415,7 @@ void GC_stop_world()
        changes = result;
        prev_list = act_list;
        prevcount = listcount;
+        vm_deallocate(current_task(), (vm_address_t)act_list, sizeof(thread_t) * listcount);
       } while (changes);
       
  
@@ -463,6 +487,7 @@ void GC_start_world()
        }
       }
     }
+    vm_deallocate(current_task(), (vm_address_t)act_list, sizeof(thread_t) * listcount);
 #   if DEBUG_THREADS
      GC_printf0("World started\n");
 #   endif
index 63031d5a3fa4c75a183c6b4e742b468747914365..18c2f6c9b760f577c94696e5fcc4c429a602cbab 100644 (file)
@@ -16,6 +16,8 @@
 
 #include "config.h"
 
+#include <errno.h>
+#include <string.h>
 #include "private/dbg_mlc.h"
 
 void GC_default_print_heap_obj_proc();
@@ -715,6 +717,26 @@ GC_PTR p;
     return (GC_store_debug_info(result, (word)lb, s, (word)i));
 }
 
+# ifdef __STDC__
+    char *GC_debug_strdup(const char *str, GC_EXTRA_PARAMS)
+#else
+    char *GC_debug_strdup(str, s, i)
+    char *str;
+    char *s;
+    int i;
+#endif
+{
+    char *copy;
+    if (str == NULL) return NULL;
+    copy = GC_debug_malloc_atomic(strlen(str) + 1, OPT_RA s, i);
+    if (copy == NULL) {
+      errno = ENOMEM;
+      return NULL;
+    }
+    strcpy(copy, str);
+    return copy;
+}
+
 # ifdef __STDC__
     GC_PTR GC_debug_malloc_uncollectable(size_t lb, GC_EXTRA_PARAMS)
 # else
index a19cb3021b0aa9568f3ec265e4aca5a2961606ce..46651ecbbd8d83a962a6a1dca364be9e189da620 100644 (file)
@@ -28,7 +28,7 @@ are GPL'ed, but with an exception that should cover all uses in the
 collector.  (If you are concerned about such things, I recommend you look
 at the notice in config.guess or ltmain.sh.)
 
-This is version 6.6 of a conservative garbage collector for C and C++.
+This is version 6.7 of a conservative garbage collector for C and C++.
 
 You might find a more recent version of this at
 
index 97b0b684dde5b556750993056e3240d3bee1c2f5..2b6ff9ac2fc1f667e9b0f46c69f5d323ea05748b 100644 (file)
@@ -2245,6 +2245,45 @@ Since 6.5
    to Ben Hutchings for the observation and patch.)
  - Move up struct callinfo declaration to make gcc 4.0.2. happy.
 
+Since 6.6:
+ - Add "int" to Solaris "end" and "etext" declaration in gc.h.  Declared
+   the symbols with underscores and as arrays, since that's what's actually
+   used.  Perhaps this could all just be removed?  (Thanks to John Bowman.)
+ - Fixed ARM GC_test_and_set code.  (Thanks to Kazu Hirata and Paul Brook.)
+ - Added casts for assignments to hb_last_reclaimed, which truncate the
+   value.  Added a cast to GC_adj_words_allocd.  Use GetModuleHandleA
+   when retrieving a handle to kernel32.dll under win32.  (Thanks to the
+   Visual Prolog developers.)
+ - Added Tandem S-Series support.  (Thanks to Craig McDaniel.  A modified
+   version of his patch was applied, and hence breakage is probably not
+   his fault.)
+ - Remove spurious gc:: qualifier for operator delete[] in gc_cpp.h.
+   (Thanks to Hanno Boeck.)
+ - Changed a test for LINUX in config_macros.h to one for __linux__.
+ - Fix ppc 64 test_and_set code by removing it.  (Thanks to Christian
+   Thalinger.)
+ - Add prototypes for GC_finalizer_notifier and GC_thr_init.  (Thanks to
+   David Ayers.)
+ - Use ld instead of nonexistent ldz instruction in Darwin FindTopOfStack.
+   (Thanks to Andreas Tobler.)
+ - Add support for Darwin/X86.  (Thanks to Geoff Norton and the Mono
+   developers.)
+ - Merge in some recent gcc fixes.  Add ppc64 asm code.  (Thanks to Bryce
+   McKinley and other gcj developers.)
+ - Scan MEM_PRIVATE sections under Windows ME and predecessors.
+ - Interior pointers with some largish offsets into large objects could
+   be ignored, if GC_all_interior_pointers was set.  (Oddly this worked
+   correctly for stack references if it was not set.  Otherwise it failed
+   for both stack and heap references.)  Thanks to Andrew McKinlay for the
+   critical test case.
+ - Integrated Tatsuya Bizenn's NETBSD threads support, with some
+   minimally tested changes.
+ - Added GC_strdup and friends to make leak detection work correctly
+   for strdup clients.  (Thanks to Jon Moore.)  Fixed the existing strdup
+   with malloc redirection to handle a null malloc return correctly.
+ - Fix Makefile.am, so it handles exe extensions under Cygwin correctly
+   for gctest.
+
 To do:
  - The USE_MUNMAP code should really use a separate data structure
    indexed by physical page to keep track of time since last use of
index 1716514bec164376f768bcedb4889f54e74f8758..ed16950e2f0b342676eb3cc0f670794bb022378f 100644 (file)
@@ -34,6 +34,12 @@ after defining the appropriate <TT>GC_</tt><I>XXXX</i><TT>_THREADS</tt> macro.
 The header file <TT>gc.h</tt> must be included
 in files that use either GC or threads primitives, since threads primitives
 will be redefined to cooperate with the GC on many platforms.
+<P>
+Thread users should also be aware that on many platforms objects reachable
+only from thread-local variables may be prematurely reclaimed.
+Thus objects pointed to by thread-local variables should also be pointed to
+by a globally visible data structure.  (This is viewed as a bug, but as
+one that is exceedingly hard to fix without some libc hooks.)
 <DL>
 <DT> <B>void * GC_MALLOC(size_t <I>nbytes</i>)</b>
 <DD>
@@ -180,6 +186,11 @@ but are scanned for pointers to collectable objects.
 They are allocated by <TT>GC_MALLOC_UNCOLLECTABLE</tt>, as described
 above, and through some interfaces described below.
 <P>
+(On most platforms, the collector may not trace correctly from in-flight
+exception objects.  Thus objects thrown as exceptions should only
+point to otherwise reachable memory.  This is another bug whose
+proper repair requires platform hooks.)
+<P>
 The easiest way to ensure that collectable objects are properly referenced
 is to allocate only collectable objects.  This requires that every
 allocation go through one of the following interfaces, each one of
index 5f64df438e32cee7f17a08ec3a6a90caa2fccd54..6d4efabdf3d2ce7aba54fdee6086dedae5e91c4a 100644 (file)
@@ -779,8 +779,8 @@ void GC_register_dynamic_libraries()
   /* this automatically, and rely largely on user input.       */
   /* We expect that any mapping with type MEM_MAPPED (which    */
   /* apparently excludes library data sections) can be safely  */
-  /* ignored.  But we're too chicken to do that in this        */
-  /* version.                                                  */
+  /* ignored.  But we're too completely remove this code in    */
+  /* this version.                                             */
   /* Based on a very limited sample, it appears that:          */
   /*   - Frame buffer mappings appear as mappings of large     */
   /*     length, usually a bit less than a power of two.       */
@@ -847,6 +847,9 @@ void GC_register_dynamic_libraries()
   }
 # endif /* DEBUG_VIRTUALQUERY */
 
+  extern GC_bool GC_wnt;  /* Is Windows NT derivative.         */
+                         /* Defined and set in os_dep.c.       */
+
   void GC_register_dynamic_libraries()
   {
     MEMORY_BASIC_INFORMATION buf;
@@ -888,7 +891,12 @@ void GC_register_dynamic_libraries()
                 * !is_frame_buffer(p, buf.RegionSize, buf.Type)
                 * instead of just checking for MEM_IMAGE.
                 * If something breaks, change it back. */
-               && buf.Type == MEM_IMAGE) {  
+               /* There is some evidence that we cannot always
+                * ignore MEM_PRIVATE sections under Windows ME
+                * and predecessors.  Hence we now also check for
+                * that case.   */
+               && (buf.Type == MEM_IMAGE ||
+                   !GC_wnt && buf.Type == MEM_PRIVATE)) {  
 #              ifdef DEBUG_VIRTUALQUERY
                  GC_dump_meminfo(&buf);
 #              endif
index 3ad891be7a9f097a8c57178d18078369b5b23dd6..533b59d1037dd630c48bbe9d6bbef31844bb5705 100644 (file)
@@ -212,7 +212,7 @@ register struct hblk * h;
     result = alloc_hdr();
     SET_HDR(h, result);
 #   ifdef USE_MUNMAP
-       result -> hb_last_reclaimed = GC_gc_no;
+       result -> hb_last_reclaimed = (unsigned short)GC_gc_no;
 #   endif
     return(result);
 }
index 445e8ec77b01549a974a31c4359a832d87741ae7..2b151363b96ada4c357fd5d2d4c9d545d3bc6a70 100644 (file)
@@ -129,7 +129,7 @@ GC_API int GC_java_finalization;
                        /* ordered finalization.  Default value is      */
                        /* determined by JAVA_FINALIZATION macro.       */
 
-GC_API void (* GC_finalizer_notifier)();
+GC_API void (* GC_finalizer_notifier) GC_PROTO((void));
                        /* Invoked by the collector when there are      */
                        /* objects to be finalized.  Invoked at most    */
                        /* once per GC cycle.  Never invoked unless     */
@@ -272,6 +272,7 @@ int GC_signum2();
  */
 GC_API GC_PTR GC_malloc GC_PROTO((size_t size_in_bytes));
 GC_API GC_PTR GC_malloc_atomic GC_PROTO((size_t size_in_bytes));
+GC_API char *GC_strdup GC_PROTO((const char *str));
 GC_API GC_PTR GC_malloc_uncollectable GC_PROTO((size_t size_in_bytes));
 GC_API GC_PTR GC_malloc_stubborn GC_PROTO((size_t size_in_bytes));
 
@@ -530,6 +531,8 @@ GC_API GC_PTR GC_debug_malloc
        GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS));
 GC_API GC_PTR GC_debug_malloc_atomic
        GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS));
+GC_API char *GC_debug_strdup
+       GC_PROTO((const char *str, GC_EXTRA_PARAMS));
 GC_API GC_PTR GC_debug_malloc_uncollectable
        GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS));
 GC_API GC_PTR GC_debug_malloc_stubborn
@@ -564,6 +567,7 @@ GC_API GC_PTR GC_debug_realloc_replacement
 # ifdef GC_DEBUG
 #   define GC_MALLOC(sz) GC_debug_malloc(sz, GC_EXTRAS)
 #   define GC_MALLOC_ATOMIC(sz) GC_debug_malloc_atomic(sz, GC_EXTRAS)
+#   define GC_STRDUP(s) GC_debug_strdup((s), GC_EXTRAS)
 #   define GC_MALLOC_UNCOLLECTABLE(sz) \
                        GC_debug_malloc_uncollectable(sz, GC_EXTRAS)
 #   define GC_MALLOC_IGNORE_OFF_PAGE(sz) \
@@ -587,6 +591,7 @@ GC_API GC_PTR GC_debug_realloc_replacement
 # else
 #   define GC_MALLOC(sz) GC_malloc(sz)
 #   define GC_MALLOC_ATOMIC(sz) GC_malloc_atomic(sz)
+#   define GC_STRDUP(s) GC_strdup(s)
 #   define GC_MALLOC_UNCOLLECTABLE(sz) GC_malloc_uncollectable(sz)
 #   define GC_MALLOC_IGNORE_OFF_PAGE(sz) \
                        GC_malloc_ignore_off_page(sz)
@@ -898,7 +903,7 @@ GC_API void (*GC_is_visible_print_proc)
 GC_PTR GC_malloc_many(size_t lb);
 #define GC_NEXT(p) (*(GC_PTR *)(p))    /* Retrieve the next element    */
                                        /* in returned list.            */
-extern void GC_thr_init();     /* Needed for Solaris/X86       */
+extern void GC_thr_init GC_PROTO((void));/* Needed for Solaris/X86     */
 
 #endif /* THREADS && !SRC_M3 */
 
@@ -949,8 +954,16 @@ extern void GC_thr_init(); /* Needed for Solaris/X86       */
      * from the statically loaded program section.
      * This circumvents a Solaris 2.X (X<=4) linker bug.
      */
-#   define GC_INIT() { extern end, etext; \
-                      GC_noop(&end, &etext); }
+#   ifdef __cplusplus
+#     define GC_INIT() { extern int _end[], _etext[]; \
+                        extern "C" void GC_noop1(GC_word); \
+                        GC_noop1((GC_word)_end); \
+                        GC_noop1((GC_word)_etext); }
+#   else
+#     define GC_INIT() { extern int _end[], _etext[]; \
+                        extern void GC_noop(); \
+                        GC_noop(_end, _etext); }
+#   endif /* !__cplusplus */
 #else
 # if defined(__CYGWIN32__) || defined (_AIX)
     /*
index 4671864b89bc56a31e1cd6aeb5bb445c6d98995b..8e3a8ae2ae9ec715164514d2ed85303405d06db8 100644 (file)
                             || defined(GC_SOLARIS_PTHREADS) \
                             || defined(GC_HPUX_THREADS) \
                             || defined(GC_AIX_THREADS) \
-                            || defined(GC_LINUX_THREADS))
+                            || defined(GC_LINUX_THREADS) \
+                            || defined(GC_NETBSD_THREADS))
 # define _REENTRANT
        /* Better late than never.  This fails if system headers that   */
        /* depend on this were previously included.                     */
 #endif
 
+#if !defined(_PTHREADS) && defined(GC_NETBSD_THREADS)
+# define _PTHREADS
+#endif
+
 #if defined(GC_DGUX386_THREADS) && !defined(_POSIX4A_DRAFT10_SOURCE)
 # define _POSIX4A_DRAFT10_SOURCE 1
 #endif
@@ -56,7 +61,7 @@
        defined(GC_IRIX_THREADS) || defined(GC_LINUX_THREADS) || \
        defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) || \
        defined(GC_DGUX386_THREADS) || defined(GC_DARWIN_THREADS) || \
-       defined(GC_AIX_THREADS) || \
+        defined(GC_AIX_THREADS) || defined(GC_NETBSD_THREADS) || \
         (defined(GC_WIN32_THREADS) && defined(__CYGWIN32__))
 #   define GC_PTHREADS
 # endif
@@ -66,7 +71,7 @@
 #   define GC_LINUX_THREADS
 #   define GC_PTHREADS
 # endif
-# if !defined(LINUX) && (defined(_PA_RISC1_1) || defined(_PA_RISC2_0) \
+# if !defined(__linux__) && (defined(_PA_RISC1_1) || defined(_PA_RISC2_0) \
                          || defined(hppa) || defined(__HPPA))
 #   define GC_HPUX_THREADS
 #   define GC_PTHREADS
 #   define GC_FREEBSD_THREADS
 #   define GC_PTHREADS
 # endif
+# if !defined(GC_PTHREADS) && defined(__NetBSD__)
+#   define GC_NETBSD_THREADS
+#   define GC_PTHREADS
+# endif
 # if defined(DGUX) && (defined(i386) || defined(__i386__))
 #   define GC_DGUX386_THREADS
 #   define GC_PTHREADS
index 4f56f0d965fcf360112686fb0cdfb86fe315a468..da2fac025ae86c79d32c5d551c1a08006cf842e4 100644 (file)
@@ -180,7 +180,7 @@ class gc {public:
     inline void* operator new[]( size_t size, void *p );
     inline void operator delete[]( void* obj );
 #   ifdef GC_PLACEMENT_DELETE
-      inline void gc::operator delete[]( void*, void* );
+      inline void operator delete[]( void*, void* );
 #   endif
 #endif /* GC_OPERATOR_NEW_ARRAY */
     };    
index 842518cfcc48c2a0657b1cc6581994abf5cd8a44..21e9c9fa605fc15e4f3c29ce7a21861c226aa7fd 100644 (file)
@@ -73,6 +73,9 @@
 # define pthread_detach GC_pthread_detach
 
 #ifndef GC_DARWIN_THREADS
+# ifdef pthread_sigmask
+#  undef pthread_sigmask
+# endif         /* pthread_sigmask */
 # define pthread_sigmask GC_pthread_sigmask
 # define dlopen GC_dlopen
 #endif
index 0674ab4d09f6d1db7bc625b058145186cee75df6..1d02f400761f3b9920821c58786efa442d294a9f 100644 (file)
@@ -4,4 +4,6 @@
 #define calloc(m,n) GC_MALLOC((m)*(n))
 #define free(p) GC_FREE(p)
 #define realloc(p,n) GC_REALLOC((p),(n))
+#undef strdup
+#define strdup(s) GC_STRDUP((s))
 #define CHECK_LEAKS() GC_gcollect()
index 1e6ea291ee9ae2f4ac10f6b6a029d3d83ef09c64..89638f6eb63e1da7f7fdc150940954f22b9a9427 100644 (file)
 #    ifdef ARM32
         inline static int GC_test_and_set(volatile unsigned int *addr) {
           int oldval;
-          /* SWP on ARM is very similar to XCHG on x86.  Doesn't lock the
-           * bus because there are no SMP ARM machines.  If/when there are,
-           * this code will likely need to be updated. */
-          /* See linuxthreads/sysdeps/arm/pt-machine.h in glibc-2.1 */
-          __asm__ __volatile__("swp %0, %1, [%2]"
-                            : "=r"(oldval)
-                            : "r"(1), "r"(addr)
-                            : "memory");
+          /* SWP on ARM is very similar to XCHG on x86.                */
+         /* The first operand is the result, the second the value      */
+         /* to be stored.  Both registers must be different from addr. */
+         /* Make the address operand an early clobber output so it     */
+         /* doesn't overlap with the other operands.  The early clobber*/
+         /* on oldval is neccessary to prevent the compiler allocating */
+         /* them to the same register if they are both unused.         */
+          __asm__ __volatile__("swp %0, %2, [%3]"
+                             : "=&r"(oldval), "=&r"(addr)
+                             : "r"(1), "1"(addr)
+                             : "memory");
           return oldval;
         }
 #       define GC_TEST_AND_SET_DEFINED
index 51981914dc5fcf71e5fa54680fdadc33c9390392..714fc428ee8aa32d160df816297dd67cb88922ff 100644 (file)
@@ -248,7 +248,8 @@ exit_label: ; \
        if (map_entry == OFFSET_TOO_BIG) { \
          map_entry = displ % (hhdr -> hb_sz); \
          displ -= map_entry; \
-         if (displ + (hhdr -> hb_sz) > BYTES_TO_WORDS(HBLKSIZE)) { \
+         if (displ + (hhdr -> hb_sz) > BYTES_TO_WORDS(HBLKSIZE) \
+             && displ != 0) { \
            GC_ADD_TO_BLACK_LIST_NORMAL((word)current, source); \
            goto exit_label; \
          } \
index 3d634ceebfdf2d2455e5cb43e7325edb02725e77..2abd27dd7054268d9b5a61adc6bf944fbb3bae9c 100644 (file)
@@ -755,17 +755,9 @@ struct hblk {
 # ifdef LARGE_CONFIG
 #   define MAX_ROOT_SETS 4096
 # else
-#   ifdef PCR
-#     define MAX_ROOT_SETS 1024
-#   else
-#     if defined(MSWIN32) || defined(MSWINCE)
-#      define MAX_ROOT_SETS 1024
-           /* Under NT, we add only written pages, which can result    */
-           /* in many small root sets.                                 */
-#     else
-#       define MAX_ROOT_SETS 256
-#     endif
-#   endif
+    /* GCJ LOCAL: MAX_ROOT_SETS increased to permit more shared */
+    /* libraries to be loaded.                                  */ 
+#   define MAX_ROOT_SETS 1024
 # endif
 
 # define MAX_EXCLUSIONS (MAX_ROOT_SETS/4)
index 276f8e04639a7376c9deb90a952bfcef69760cc8..c723318c971d8554d36900ab452992a667bc3899 100644 (file)
 #   if defined(__ppc__)  || defined(__ppc64__)
 #    define POWERPC
 #    define mach_type_known
-#   elif defined(__i386__)
+#   endif
+#   if defined(__i386__)
 #    define I386
-     --> Not really supported, but at least we recognize it.
+#    define mach_type_known
 #   endif
 # endif
 # if defined(NeXT) && defined(mc68000)
 #     define  mach_type_known
 #    endif 
 # endif
+# if defined(__TANDEM)
+    /* Nonstop S-series */
+    /* FIXME: Should recognize Integrity series? */
+#   define MIPS
+#   define NONSTOP
+#   define mach_type_known
+# endif
 
 /* Feel free to add more clauses here */
 
                    /*               FREEBSD, THREE86BSD, MSWIN32,      */
                    /*               BSDI,SUNOS5, NEXT, other variants) */
                     /*             NS32K      ==> Encore Multimax      */
-                    /*             MIPS       ==> R2000 or R3000       */
-                    /*                 (RISCOS, ULTRIX variants)       */
+                   /*             MIPS       ==> R2000 through R14K    */
+                    /*                 (many variants)                 */
                     /*            VAX        ==> DEC VAX               */
                     /*                 (BSD, ULTRIX variants)          */
                     /*            RS6000     ==> IBM RS/6000 AIX3.X    */
 /* #     define MPROTECT_VDB  Not quite working yet? */
 #     define DYNAMIC_LOADING
 #   endif
+#   ifdef DARWIN
+#     define OS_TYPE "DARWIN"
+#     define DARWIN_DONT_PARSE_STACK
+#     define DYNAMIC_LOADING
+      /* XXX: see get_end(3), get_etext() and get_end() should not be used.
+        These aren't used when dyld support is enabled (it is by default) */
+#     define DATASTART ((ptr_t) get_etext())
+#     define DATAEND   ((ptr_t) get_end())
+#     define STACKBOTTOM ((ptr_t) 0xc0000000)
+#     define USE_MMAP
+#     define USE_MMAP_ANON
+#     define USE_ASM_PUSH_REGS
+      /* This is potentially buggy. It needs more testing. See the comments in
+        os_dep.c.  It relies on threads to track writes. */
+#     ifdef GC_DARWIN_THREADS
+/* #       define MPROTECT_VDB -- disabled for now.  May work for some apps. */
+#     endif
+#     include <unistd.h>
+#     define GETPAGESIZE() getpagesize()
+      /* There seems to be some issues with trylock hanging on darwin. This
+         should be looked into some more */
+#      define NO_PTHREAD_TRYLOCK
+#   endif /* DARWIN */
 # endif
 
 # ifdef NS32K
 #       define DATAEND /* not needed */
 #   endif
 #   if defined(NETBSD)
-#     define ALIGNMENT 4
 #     define OS_TYPE "NETBSD"
+#     define ALIGNMENT 4
 #     define HEURISTIC2
 #     define USE_GENERIC_PUSH_REGS
 #     ifdef __ELF__
 #       define STACKBOTTOM ((ptr_t) 0x7ffff000)
 #     endif /* _ELF_ */
 #  endif
+#  if defined(NONSTOP)
+#    define CPP_WORDSZ 32
+#    define OS_TYPE "NONSTOP"
+#    define ALIGNMENT 4
+#    define DATASTART ((ptr_t) 0x08000000)
+     extern int _end[];
+#    define DATAEND (_end)
+#    define STACKBOTTOM ((ptr_t) 0x4fffffff)
+#    define USE_GENERIC_PUSH_REGS
+#   endif
 # endif
 
 # ifdef RS6000
 #      define OS_TYPE "NETBSD"
 #      define HEURISTIC2
 #      define DATASTART GC_data_start
-#       define USE_GENERIC_PUSH_REGS
+#      define USE_GENERIC_PUSH_REGS
 #      define DYNAMIC_LOADING
 #   endif
 # endif
 #   define SUNOS5SIGS
 # endif
 
+# ifdef GC_NETBSD_THREADS
+#   define SIGRTMIN 33
+#   define SIGRTMAX 63
+# endif
+
 # if defined(SVR4) || defined(LINUX) || defined(IRIX5) || defined(HPUX) \
            || defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) \
            || defined(DGUX) || defined(BSD) || defined(SUNOS4) \
 # if defined(GC_LINUX_THREADS) && !defined(LINUX)
        --> inconsistent configuration
 # endif
+# if defined(GC_NETBSD_THREADS) && !defined(NETBSD)
+       --> inconsistent configuration
+# endif
 # if defined(GC_SOLARIS_THREADS) && !defined(SUNOS5)
        --> inconsistent configuration
 # endif
                                            + GC_page_size) \
                                            + GC_page_size-1)
 #   else
-#     if defined(NEXT) || defined(DOS4GW) || \
+#     if defined(NEXT) || defined(DOS4GW) || defined(NONSTOP) || \
                 (defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) || \
                 (defined(SUNOS5) && !defined(USE_MMAP))
 #       define GET_MEM(bytes) HBLKPTR((size_t) \
index b3d559880d6b7de3985e54bfd3f1cb0615613266..a7555d838c4a084b23250270e52a2b265319b2e3 100644 (file)
@@ -17,6 +17,8 @@
 #include "config.h"
  
 #include <stdio.h>
+#include <string.h>
+#include <errno.h>
 #include "private/gc_priv.h"
 
 extern ptr_t GC_clear_stack(); /* in misc.c, behaves like identity */
@@ -273,6 +275,26 @@ DCL_LOCK_STATE;
    }
 }
 
+/* provide a version of strdup() that uses the collector to allocate the
+   copy of the string */
+# ifdef __STDC__
+    char *GC_strdup(const char *s)
+# else
+    char *GC_strdup(s)
+    char *s;
+#endif
+{
+  char *copy;
+
+  if (s == NULL) return NULL;
+  if ((copy = GC_malloc_atomic(strlen(s) + 1)) == NULL) {
+    errno = ENOMEM;
+    return NULL;
+  }
+  strcpy(copy, s);
+  return copy;
+}
+
 /* Allocate lb bytes of composite (pointerful) data */
 # ifdef __STDC__
     GC_PTR GC_malloc(size_t lb)
@@ -372,6 +394,10 @@ DCL_LOCK_STATE;
   {
     size_t len = strlen(s) + 1;
     char * result = ((char *)REDIRECT_MALLOC(len+1));
+    if (result == 0) {
+      errno = ENOMEM;
+      return 0;
+    }
     BCOPY(s, result, len+1);
     return result;
   }
index 382a1887b46c925392bd59f2ed104c0372953ec1..057534938b9ac529ce10face6f8ae9858aec3b28 100644 (file)
@@ -1487,7 +1487,6 @@ ptr_t top;
 ptr_t cold_gc_frame;
 {
   if (!NEED_FIXUP_POINTER && GC_all_interior_pointers) {
-#   define EAGER_BYTES 1024
     /* Push the hot end of the stack eagerly, so that register values   */
     /* saved inside GC frames are marked before they disappear.                */
     /* The rest of the marking can be deferred until later.            */
index 1334ef1e6db5b5ac490461b25811c6f93ae28865..2c8d314aa0d96a906168467faa750505f15368d5 100644 (file)
 # include <tchar.h>
 #endif
 
+#ifdef NONSTOP
+# include <floss.h>
+#endif
+
 # ifdef THREADS
 #   ifdef PCR
 #     include "il/PCR_IL.h"
@@ -478,10 +482,11 @@ void GC_init()
 #if defined(GC_WIN32_THREADS) && !defined(GC_PTHREADS)
     if (!GC_is_initialized) {
       BOOL (WINAPI *pfn) (LPCRITICAL_SECTION, DWORD) = NULL;
-      HMODULE hK32 = GetModuleHandle("kernel32.dll");
+      HMODULE hK32 = GetModuleHandleA("kernel32.dll");
       if (hK32)
-          (FARPROC) pfn = GetProcAddress(hK32,
-                         "InitializeCriticalSectionAndSpinCount");
+         pfn = (BOOL (WINAPI *) (LPCRITICAL_SECTION, DWORD))
+               GetProcAddress (hK32,
+                               "InitializeCriticalSectionAndSpinCount");
       if (pfn)
           pfn(&GC_allocate_ml, 4000);
       else
index e5e9f10e3f406a91049e7713e2c3b55a87fab766..17f5c8f0928e5b23ddb7dff26f544321e11fa997 100644 (file)
@@ -1183,12 +1183,15 @@ void GC_register_data_segments()
        /* This used to be set for gcc, to avoid dealing with           */
        /* the structured exception handling issues.  But we now have   */
        /* assembly code to do that right.                              */
+  GC_bool GC_wnt = FALSE;
+        /* This is a Windows NT derivative, i.e. NT, W2K, XP or later.  */
   
   void GC_init_win32()
   {
     /* if we're running under win32s, assume that no DLLs will be loaded */
     DWORD v = GetVersion();
-    GC_no_win32_dlls |= ((v & 0x80000000) && (v & 0xff) <= 3);
+    GC_wnt = !(v & 0x80000000);
+    GC_no_win32_dlls |= ((!GC_wnt) && (v & 0xff) <= 3);
   }
 
   /* Return the smallest address a such that VirtualQuery              */
@@ -1500,7 +1503,7 @@ void GC_register_data_segments()
 
 # if !defined(OS2) && !defined(PCR) && !defined(AMIGA) \
        && !defined(MSWIN32) && !defined(MSWINCE) \
-       && !defined(MACOS) && !defined(DOS4GW)
+       && !defined(MACOS) && !defined(DOS4GW) && !defined(NONSTOP)
 
 # ifdef SUNOS4
     extern caddr_t sbrk();
@@ -3801,8 +3804,12 @@ catch_exception_raise(
         mach_msg_type_number_t exc_state_count = PPC_EXCEPTION_STATE64_COUNT;
         ppc_exception_state64_t exc_state;
 #     endif
+#   elif defined(I386)
+        thread_state_flavor_t flavor = i386_EXCEPTION_STATE;
+        mach_msg_type_number_t exc_state_count = i386_EXCEPTION_STATE_COUNT;
+        i386_exception_state_t exc_state;
 #   else
-#      error FIXME for non-ppc darwin
+#      error FIXME for non-ppc/x86 darwin
 #   endif
 
     
@@ -3832,7 +3839,13 @@ catch_exception_raise(
     }
     
     /* This is the address that caused the fault */
+#if defined(POWERPC)
     addr = (char*) exc_state.dar;
+#elif defined (I386)
+    addr = (char*) exc_state.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 
index fd23110b80b511db8d95e32e6629587b7e62907b..1121ee89c6e4661853a500fd1484f2684f594059 100644 (file)
@@ -1,10 +1,21 @@
+#if defined(__ppc64__)
+#define MODE_CHOICE(x, y) y
+#else
+#define MODE_CHOICE(x, y) x
+#endif
+
+#define lgu     MODE_CHOICE(lwzu, ldu)
+
+#define g_long  MODE_CHOICE(long, quad)         /* usage is ".g_long" */
+
+#define LOG2_GPR_BYTES  MODE_CHOICE(2,3)        /* log2(GPR_BYTES) */
 
 ; GC_push_regs function. Under some optimization levels GCC will clobber
 ; some of the non-volatile registers before we get a chance to save them
 ; therefore, this cannot be inline asm.
 
 .text
-       .align 2
+       .align LOG2_GPR_BYTES
        .globl _GC_push_regs
 _GC_push_regs:
     
@@ -65,7 +76,7 @@ _GC_push_regs:
 
 .data
 .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
-       .align 2
+       .align LOG2_GPR_BYTES
 L_GC_push_one$stub:
        .indirect_symbol _GC_push_one
        mflr r0
@@ -74,12 +85,11 @@ L0$_GC_push_one:
        mflr r11
        addis r11,r11,ha16(L_GC_push_one$lazy_ptr-L0$_GC_push_one)
        mtlr r0
-       lwzu r12,lo16(L_GC_push_one$lazy_ptr-L0$_GC_push_one)(r11)
+       lgu r12,lo16(L_GC_push_one$lazy_ptr-L0$_GC_push_one)(r11)
        mtctr r12
        bctr
 .data
 .lazy_symbol_pointer
 L_GC_push_one$lazy_ptr:
        .indirect_symbol _GC_push_one
-       .long dyld_stub_binding_helper
-
+       .g_long dyld_stub_binding_helper
index 0a86e323cc8df92ba5dbb027cf83e880fdc2ba4c..c24d251073bf36dad21974f70a85923f3258d3e4 100644 (file)
@@ -109,7 +109,7 @@ void GC_brief_async_signal_safe_sleep()
  */
 
 #ifndef SIG_THR_RESTART
-#  if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
+#  if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) || defined(GC_NETBSD_THREADS)
 #    ifdef _SIGRTMIN
 #      define SIG_THR_RESTART _SIGRTMIN + 5
 #    else
@@ -122,6 +122,13 @@ void GC_brief_async_signal_safe_sleep()
 
 sem_t GC_suspend_ack_sem;
 
+#ifdef GC_NETBSD_THREADS
+# define GC_NETBSD_THREADS_WORKAROUND
+  /* It seems to be necessary to wait until threads have restarted.    */
+  /* But it is unclear why that is the case.                           */
+  sem_t GC_restart_ack_sem;
+#endif
+
 void GC_suspend_handler_inner(ptr_t sig_arg);
 int cacao_suspendhandler(void *);
 
@@ -234,6 +241,10 @@ void GC_restart_handler(int sig)
 
     if (sig != SIG_THR_RESTART) ABORT("Bad signal in suspend_handler");
 
+#ifdef GC_NETBSD_THREADS_WORKAROUND
+    sem_post(&GC_restart_ack_sem);
+#endif
+
     /*
     ** Note: even if we don't do anything useful here,
     ** it would still be necessary to have a signal handler,
@@ -310,6 +321,8 @@ void GC_push_all_stacks()
                (unsigned long) bs_lo, (unsigned long) bs_hi);
 #        endif
           if (pthread_equal(p -> id, me)) {
+           /* FIXME:  This may add an unbounded number of entries,     */
+           /* and hence overflow the mark stack, which is bad.         */
            GC_push_all_eager(bs_lo, bs_hi);
          } else {
            GC_push_all_stack(bs_lo, bs_hi);
@@ -451,6 +464,9 @@ void GC_start_world()
     register GC_thread p;
     register int n_live_threads = 0;
     register int result;
+#ifdef GC_NETBSD_THREADS_WORKAROUND
+    int code;
+#endif
 
 #   if DEBUG_THREADS
       GC_printf0("World starting\n");
@@ -480,6 +496,14 @@ void GC_start_world()
         }
       }
     }
+#ifdef GC_NETBSD_THREADS_WORKAROUND
+    for (i = 0; i < n_live_threads; i++)
+       while (0 != (code = sem_wait(&GC_restart_ack_sem)))
+           if (errno != EINTR) {
+               GC_err_printf1("sem_wait() returned %ld\n", (unsigned long)code);
+               ABORT("sem_wait() for restart handler failed");
+           }
+#endif
 
        unlock_stopworld();
 
@@ -493,6 +517,10 @@ void GC_stop_init() {
     
     if (sem_init(&GC_suspend_ack_sem, 0, 0) != 0)
         ABORT("sem_init failed");
+#ifdef GC_NETBSD_THREADS_WORKAROUND
+    if (sem_init(&GC_restart_ack_sem, 0, 0) != 0)
+       ABORT("sem_init failed");
+#endif
 
     act.sa_flags = SA_RESTART | SA_SIGINFO;
     if (sigfillset(&act.sa_mask) != 0) {
index 1c6703e7ff6712fca8cc5050cc44a659c177a763..c462f27b96eb0e87075249fbbf4793a27d272b93 100644 (file)
@@ -69,7 +69,8 @@
 # endif
 
 # if (defined(GC_DGUX386_THREADS) || defined(GC_OSF1_THREADS) || \
-      defined(GC_DARWIN_THREADS) || defined(GC_AIX_THREADS)) \
+      defined(GC_DARWIN_THREADS) || defined(GC_AIX_THREADS) || \
+      defined(GC_NETBSD_THREADS))                             \
       && !defined(USE_PTHREAD_SPECIFIC)
 #   define USE_PTHREAD_SPECIFIC
 # endif
 # include <sys/sysctl.h>
 #endif /* GC_DARWIN_THREADS */
 
-
+#if defined(GC_NETBSD_THREADS)
+# include <sys/param.h>
+# include <sys/sysctl.h>
+#endif /* GC_NETBSD_THREADS */
 
 #if defined(GC_DGUX386_THREADS)
 # include <sys/dg_sys_info.h>
@@ -838,6 +842,18 @@ int GC_get_nprocs()
 }
 #endif /* GC_DGUX386_THREADS */
 
+#if defined(GC_NETBSD_THREADS)
+static int get_ncpu(void)
+{
+    int mib[] = {CTL_HW,HW_NCPU};
+    int res;
+    size_t len = sizeof(res);
+
+    sysctl(mib, sizeof(mib)/sizeof(int), &res, &len, NULL, 0);
+    return res;
+}
+#endif /* GC_NETBSD_THREADS */
+
 /* We hold the allocation lock.        */
 void GC_thr_init()
 {
@@ -883,6 +899,9 @@ void GC_thr_init()
          GC_nprocs = sysconf(_SC_NPROC_ONLN);
          if (GC_nprocs <= 0) GC_nprocs = 1;
 #       endif
+#       if defined(GC_NETBSD_THREADS)
+         GC_nprocs = get_ncpu();
+#       endif
 #       if defined(GC_DARWIN_THREADS) || defined(GC_FREEBSD_THREADS)
          int ncpus = 1;
          size_t len = sizeof(ncpus);
index 8d7baf9efe60b5f98162972014f2afc590816ecd..396c3d35a700730112f5b5d12085d4a24b4d0e61 100644 (file)
@@ -24,6 +24,10 @@ int main()
           printf("-pthread\n");
 #       endif
 #   endif
+#   if defined(GC_NETBSD_THREADS)
+         printf("-lpthread -lrt\n");
+#   endif
+
 #   if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
        printf("-lpthread -lrt\n");
 #   endif
index e1fe24bd0abe84e8b3f15b950721c724ec612f20..930f3f27d86c357b3be91133d45ee7b955b83beb 100644 (file)
@@ -2,7 +2,7 @@
 /* Eventually this one may become unnecessary.  For now we need        */
 /* it to keep the old-style build process working.             */
 #define GC_TMP_VERSION_MAJOR 6
-#define GC_TMP_VERSION_MINOR 6
+#define GC_TMP_VERSION_MINOR 7
 #define GC_TMP_ALPHA_VERSION GC_NOT_ALPHA
 
 #ifndef GC_NOT_ALPHA