]> granicus.if.org Git - gc/commitdiff
2006-03-09 Hans Boehm <Hans.Boehm@hp.com>
authorhboehm <hboehm>
Fri, 10 Mar 2006 05:24:07 +0000 (05:24 +0000)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 26 Jul 2011 17:06:36 +0000 (21:06 +0400)
Merge various gc6.7 changes (see doc/README.changes for contributors):
* configure.ac, pthread_stop_world.c, pthread_support.c,
threadlibs.c, include/gc_config_macros.h,
include/gc_pthread_redirects.h, include/leak_detector.h,
include/private/gcconfig.h, include/private/thread_local_alloc.h:
Add NetBSD threads support.
* dbg_mlc.c, malloc.c, include/gc.h: add GC_debug_str_dup, GC_str_dup.
* os_dep.c (GC_init_win32),
dyn_load.c (win32 GC_register_dynamic_libraries): accept
MEM_PRIVATE for Windows 98 etc.
* doc/gcinterface.html: Add warnings about thread locals and
in-flight exceptions.
* tests/tests.am: Add EXE extensions.
* Makefile.in, configure: rebuild

19 files changed:
Makefile.in
configure
configure.ac
dbg_mlc.c
doc/README.changes
doc/gcinterface.html
dyn_load.c
include/gc.h
include/gc_config_macros.h
include/gc_pthread_redirects.h
include/leak_detector.h
include/private/gcconfig.h
include/private/thread_local_alloc.h
malloc.c
os_dep.c
pthread_stop_world.c
pthread_support.c
tests/tests.am
threadlibs.c

index 68708efafec8e181c93ed458f6b275642216659c..08b02abd44871b7ffb7ee018370e404a0b27fd98 100644 (file)
@@ -109,13 +109,13 @@ DIST_COMMON = $(am__configure_deps) $(am__pkginclude_HEADERS_DIST) \
        config.guess config.sub depcomp install-sh ltmain.sh missing \
        mkinstalldirs
 
-#TESTS += tracetest
+#TESTS += tracetest$(EXEEXT)
 #check_PROGRAMS += tracetest
 #tracetest_SOURCES = tests/trace_test.c
 #tracetest_LDADD = $(test_ldadd)
-@THREADS_TRUE@am__append_1 = threadleaktest
+@THREADS_TRUE@am__append_1 = threadleaktest$(EXEEXT)
 @THREADS_TRUE@am__append_2 = threadleaktest
-@CPLUSPLUS_TRUE@am__append_3 = test_cpp
+@CPLUSPLUS_TRUE@am__append_3 = test_cpp$(EXEEXT)
 @CPLUSPLUS_TRUE@am__append_4 = test_cpp
 
 # C Library: Architecture Dependent
@@ -471,7 +471,8 @@ dist_noinst_HEADERS = include/private/gc_hdrs.h \
        include/private/darwin_stop_world.h \
        include/private/thread_local_alloc.h include/cord.h \
        include/ec.h include/javaxfc.h version.h
-TESTS = gctest leaktest middletest $(am__append_1) $(am__append_3)
+TESTS = gctest$(EXEEXT) leaktest$(EXEEXT) middletest$(EXEEXT) \
+       $(am__append_1) $(am__append_3)
 pkgconfigdir = $(libdir)/pkgconfig
 dist_pkgconfig_DATA = bdw-gc.pc
 libcord_la_SOURCES = \
index b4e9b801c914cfe0eb751c4a7803d733a5b4f23b..d0c8d506221a5fa8250bbb787d7957479d3e9e98 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
 #! /bin/sh
-# From configure.ac Revision: 1.2 .
+# From configure.ac Revision: 1.3 .
 # Guess values for system-dependent variables and create Makefiles.
 # Generated by GNU Autoconf 2.59 for gc 7.0alpha6.
 #
@@ -4156,6 +4156,23 @@ _ACEOF
        INCLUDES="$INCLUDES -pthread"
        THREADDLLIBS=-pthread
        ;;
+     *-*-netbsd*)
+       { echo "$as_me:$LINENO: WARNING: \"Only on NetBSD 2.0 or later.\"" >&5
+echo "$as_me: WARNING: \"Only on NetBSD 2.0 or later.\"" >&2;}
+       cat >>confdefs.h <<\_ACEOF
+#define GC_NETBSD_THREADS 1
+_ACEOF
+
+       cat >>confdefs.h <<\_ACEOF
+#define _REENTRANT 1
+_ACEOF
+
+       cat >>confdefs.h <<\_ACEOF
+#define _PTHREADS 1
+_ACEOF
+
+       THREADDLLIBS="-lpthread -lrt"
+       ;;
      *-*-solaris*)
        cat >>confdefs.h <<\_ACEOF
 #define GC_SOLARIS_THREADS 1
@@ -6217,7 +6234,7 @@ test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
 case $host in
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 6220 "configure"' > conftest.$ac_ext
+  echo '#line 6237 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -6790,7 +6807,7 @@ chmod -w .
 save_CFLAGS="$CFLAGS"
 CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"
 compiler_c_o=no
-if { (eval echo configure:6793: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
+if { (eval echo configure:6810: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
   # The compiler can only warn and ignore the option if not recognized
   # So say no if there are warnings
   if test -s out/conftest.err; then
@@ -8717,7 +8734,7 @@ else
     lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 8720 "configure"
+#line 8737 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -8815,7 +8832,7 @@ else
     lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 8818 "configure"
+#line 8835 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
index a89768308bd80696f2b08ae1c9cbfbd90349a348..e0684c588751b56b07b0c46f5c1ea47f7f820317 100644 (file)
@@ -22,7 +22,7 @@ AC_INIT(gc,7.0alpha6,Hans.Boehm@hp.com)
 AC_CONFIG_SRCDIR(gcj_mlc.c)
 AC_CANONICAL_TARGET 
 AC_PREREQ(2.53)
-AC_REVISION($Revision: 1.3 $)
+AC_REVISION($Revision: 1.4 $)
 GC_SET_VERSION
 AM_INIT_AUTOMAKE([foreign dist-bzip2 subdir-objects nostdinc])
 AM_MAINTAINER_MODE
@@ -113,6 +113,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)
+       AC_DEFINE(_REENTRANT)
+       AC_DEFINE(_PTHREADS)
+       THREADDLLIBS="-lpthread -lrt"
+       ;;
      *-*-solaris*)
        AC_DEFINE(GC_SOLARIS_THREADS)
        AC_DEFINE(GC_SOLARIS_PTHREADS)
index 881fa7fca56c5856c2468031cb5110baca94131b..bffa93394a4dc089ef46159e4be9fa13ec61788e 100644 (file)
--- a/dbg_mlc.c
+++ b/dbg_mlc.c
@@ -14,6 +14,8 @@
  * modified is included with the above copyright notice.
  */
 
+#include <errno.h>
+#include <string.h>
 #include "private/dbg_mlc.h"
 
 void GC_default_print_heap_obj_proc();
@@ -636,6 +638,19 @@ void * GC_debug_malloc_atomic(size_t lb, GC_EXTRA_PARAMS)
     return (GC_store_debug_info(result, (word)lb, s, (word)i));
 }
 
+char *GC_debug_strdup(const char *str, GC_EXTRA_PARAMS)
+{
+    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;
+}
+
 void * GC_debug_malloc_uncollectable(size_t lb, GC_EXTRA_PARAMS)
 {
     void * result = GC_malloc_uncollectable(lb + UNCOLLECTABLE_DEBUG_BYTES);
index bf26df4740373442282f4193418b6d3c674908d0..a396cd885674335aa9b3078066f4ebaf6445d95c 100644 (file)
@@ -2263,6 +2263,17 @@ Since 6.6:
    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
+   untested 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.
 
 Since gc6.7:
  - Remove GC_PROTO, VOLATILE, GC_PTR, and GC_CONST.  Assume ANSI C compiler
@@ -2459,6 +2470,8 @@ Since gc7.0alpha5
  - Fix typo in DARWIN section of gcconfig.h.
  - Fix Darwin thread memory leak.  (Thanks to Bruce Mitchener.)
  - Update x86 AO_test_and_set implementation to use "=q".
+ - Add $(EXEEXT) to many tests in tests/tests.am.  (Corresponds to a
+   6.7 fix, which no longer applied.)
   
 To do:
  - REDIRECT_MALLOC and threads combination is getting closer, but currently
index d8b378b1973b2403b5765521bbcca35713ba655c..74230aa6caee465d4e677511eaa4b6a557585834 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>
@@ -192,6 +198,11 @@ but are scanned for pointers to collectable objects.
 They are usually 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 3007774c4c37504605a32af6ea8510df94f01ee2..8de30b70af9d2506e8441ec9a1af78bd29850a46 100644 (file)
@@ -701,6 +701,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;
@@ -738,7 +741,12 @@ void GC_register_dynamic_libraries()
                && (protect == PAGE_EXECUTE_READWRITE
                    || protect == PAGE_READWRITE)
                && !GC_is_heap_base(buf.AllocationBase)
-               && 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 7f380f136bb5f0c741f8dc74a2648a7c467395b0..6ad52e3a7b92cc3069a34cbaaf3dc622fe869867 100644 (file)
@@ -253,6 +253,7 @@ GC_API void GC_init(void);
  */
 GC_API void * GC_malloc(size_t size_in_bytes);
 GC_API void * GC_malloc_atomic(size_t size_in_bytes);
+GC_API char * GC_strdup (const char *str);
 GC_API void * GC_malloc_uncollectable(size_t size_in_bytes);
 GC_API void * GC_malloc_stubborn(size_t size_in_bytes);
 
@@ -505,6 +506,7 @@ GC_API void * GC_malloc_atomic_ignore_off_page(size_t lb);
 /* objects allocated in this way for overwrites, etc.                  */
 GC_API void * GC_debug_malloc(size_t size_in_bytes, GC_EXTRA_PARAMS);
 GC_API void * GC_debug_malloc_atomic(size_t size_in_bytes, GC_EXTRA_PARAMS);
+GC_API char * GC_debug_strdup(const char *str, GC_EXTRA_PARAMS);
 GC_API void * GC_debug_malloc_uncollectable
        (size_t size_in_bytes, GC_EXTRA_PARAMS);
 GC_API void * GC_debug_malloc_stubborn
@@ -538,6 +540,7 @@ GC_API void * 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) \
@@ -561,6 +564,7 @@ GC_API void * 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)
index 2b8ced7982f2959d148e885df7f2e96f01c14c3f..487848e83c092afe50fb5ef16e30f61dcf1d0ee2 100644 (file)
 #if !defined(_REENTRANT) && (defined(GC_SOLARIS_THREADS) \
                             || 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
@@ -55,7 +60,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
 #   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 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 efa364c2fc5bf46732b118dafd85c704096f85cd..4c246a5a1654b438cf313d734a0cbf2b95a3a338 100644 (file)
 #   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) \
 # 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
index 3416931dfcd8bc240af8dee7cddea2dde3694061..b74e5cbc3091445623140a28e55b26bd1fe9b7dc 100644 (file)
@@ -42,7 +42,8 @@
 #   elif defined(LINUX) && defined(__GNUC__)
 #     define USE_COMPILER_TLS
 #   elif (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)
 #     define USE_PTHREAD_SPECIFIC
 #   elif defined(GC_HPUX_THREADS)
 #     ifdef __GNUC__
index 1513735fb0a04e06de8705d02191272261859b5a..47319f886784e65590d50ffbcd4c05edfbb16c7c 100644 (file)
--- a/malloc.c
+++ b/malloc.c
@@ -14,6 +14,8 @@
  */
  
 #include <stdio.h>
+#include <string.h>
+#include <errno.h>
 #include "private/gc_priv.h"
 
 extern void * GC_clear_stack(void *);  /* in misc.c, behaves like identity */
@@ -229,6 +231,26 @@ void * GC_generic_malloc(size_t lb, int k)
    }
 }
 
+/* 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 THREAD_LOCAL_ALLOC
   void * GC_core_malloc(size_t lb)
@@ -308,6 +330,10 @@ void * calloc(size_t n, size_t lb)
   {
     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 d233694ee4ba8e04c1a5c217c8441a9c0616a1bf..f2da9deeef2b9dd0de4f9e331845bce764d24873 100644 (file)
--- a/os_dep.c
+++ b/os_dep.c
@@ -1240,12 +1240,18 @@ void GC_register_data_segments(void)
     }
 
 # endif
+
+  GC_bool GC_wnt = FALSE;
+         /* This is a Windows NT derivative, i.e. NT, W2K, XP or later.  */
   
   void GC_init_win32(void)
   {
-    /* if we're running under win32s, assume that no DLLs will be loaded */
+    /* Set GC_wnt.                                                      */
+    /* If we're running under win32s, assume that no DLLs will be loaded */
+    /* I doubt anyone still runs win32s, but ...                        */
     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              */
index 33cc9e04e356d97aa6130fc8f49ec097086eb9be..301c97ba41510042142e4ab8bfe3d3686a4ec97f 100644 (file)
@@ -93,7 +93,7 @@ volatile AO_t GC_world_is_stopped = FALSE;
  */
 
 #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
@@ -106,6 +106,13 @@ volatile AO_t GC_world_is_stopped = FALSE;
 
 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, void *context);
 
 #if defined(IA64) || defined(HP_PA)
@@ -208,6 +215,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,
@@ -424,6 +435,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_printf("World starting\n");
@@ -455,6 +469,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
     #if DEBUG_THREADS
       GC_printf("World started\n");
     #endif
@@ -465,6 +487,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 a8c3c6b832675fddaadfa608da0327e1b3149891..4a283fb0f1b7636a7fab88647bdea9c03a214851 100644 (file)
 # 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 */
+
 /* Allocator lock definitions.         */
 #if defined(USE_SPIN_LOCK)
   pthread_t GC_lock_holder = NO_THREAD;
@@ -652,6 +657,18 @@ int GC_get_nprocs(void)
 }
 #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(void)
 {
@@ -698,6 +715,9 @@ void GC_thr_init(void)
          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 defd592c6ca2bd17e2ba6b06164dc440d668443f..ab6248552038464d7fcc96ee4cf7a099aee85a92 100644 (file)
@@ -23,36 +23,36 @@ test_ldadd = \
 
 
 
-TESTS += gctest
+TESTS += gctest$(EXEEXT)
 check_PROGRAMS += gctest
 gctest_SOURCES = tests/test.c
 gctest_LDADD = $(test_ldadd)
 gctest_DEPENDENCIES = $(top_builddir)/libgc.la
 
-TESTS += leaktest
+TESTS += leaktest$(EXEEXT)
 check_PROGRAMS += leaktest
 leaktest_SOURCES = tests/leak_test.c
 leaktest_LDADD = $(test_ldadd)
 
-TESTS += middletest
+TESTS += middletest$(EXEEXT)
 check_PROGRAMS += middletest
 middletest_SOURCES = tests/middle.c
 middletest_LDADD = $(test_ldadd)
 
-#TESTS += tracetest
+#TESTS += tracetest$(EXEEXT)
 #check_PROGRAMS += tracetest
 #tracetest_SOURCES = tests/trace_test.c
 #tracetest_LDADD = $(test_ldadd)
 
 if THREADS
-TESTS += threadleaktest
+TESTS += threadleaktest$(EXEEXT)
 check_PROGRAMS += threadleaktest
 threadleaktest_SOURCES = tests/thread_leak_test.c
 threadleaktest_LDADD = $(test_ldadd)
 endif
 
 if CPLUSPLUS
-TESTS += test_cpp
+TESTS += test_cpp$(EXEEXT)
 check_PROGRAMS += test_cpp
 test_cpp_SOURCES = tests/test_cpp.cc
 test_cpp_LDADD = libgccpp.la $(test_ldadd)
index 13096944cac3449e48bebee898704df9cd3b82d8..ab2118b49b53842285ec53a0f592a4f310b1e9b8 100644 (file)
@@ -27,6 +27,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