]> granicus.if.org Git - gc/commitdiff
2007-05-23 Hans Boehm <Hans.Boehm@hp.com> (Really mostly Romano Paolo Tenca)
authorhboehm <hboehm>
Thu, 24 May 2007 05:18:06 +0000 (05:18 +0000)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 26 Jul 2011 17:06:40 +0000 (21:06 +0400)
* gc_dlopen.c, thread_local_alloc.c, threadlibs.c, win32_threads.c,
tests/test.c: Accomodate GC_WIN32_PTHREADS.
* include/gc.h: Don't include windows.h for GC_WIN32_PTHREADS.
* include/gc_config_macros.h: Define both PTHREADS and
GC_WIN32_THREADS.
* include/private/gc_locks.h: Nonstandard definitions of
NUMERIC_THREAD_ID for GC_WIN32_PTHREADS.
* doc/README.win32, Makefile.direct: Include documentation
for GC_WIN32_PTHREADS.
* Makefile.direct: Remove some anachronisms in the documentation.

ChangeLog
Makefile.direct
doc/README.win32
gc_dlopen.c
include/gc.h
include/gc_config_macros.h
include/private/gc_locks.h
tests/test.c
thread_local_alloc.c
threadlibs.c
win32_threads.c

index 09ca5d4d31e13f2be774ea29062fef83a8487809..e0ab5470ba9118460e4ade5270c3366b38c7eed5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2007-05-23  Hans Boehm <Hans.Boehm@hp.com> (Really mostly Romano Paolo Tenca)
+
+       * gc_dlopen.c, thread_local_alloc.c, threadlibs.c, win32_threads.c,
+       tests/test.c: Accomodate GC_WIN32_PTHREADS.
+       * include/gc.h: Don't include windows.h for GC_WIN32_PTHREADS.
+       * include/gc_config_macros.h: Define both PTHREADS and
+       GC_WIN32_THREADS.
+       * include/private/gc_locks.h: Nonstandard definitions of
+       NUMERIC_THREAD_ID for GC_WIN32_PTHREADS.
+       * doc/README.win32, Makefile.direct: Include documentation
+       for GC_WIN32_PTHREADS.
+       * Makefile.direct: Remove some anachronisms in the documentation.
+
 2007-05-23  Hans Boehm <Hans.Boehm@hp.com>
 
        * Makefile.am: Move includes to bottom.  Add better library
index da72448059e394a439b446a44ed42704cedf01a2..e40e06ab060f93fd6ac86e523797af6d8c379f83 100644 (file)
@@ -67,28 +67,37 @@ HOSTCFLAGS=$(CFLAGS)
 #   This causes the collector to assume that all inaccessible
 #   objects should have been explicitly deallocated, and reports exceptions.
 #   Finalization and the test program are not usable in this mode.
-# -DGC_SOLARIS_THREADS enables support for Solaris (thr_) threads.
+#
+# IMPORTANT: Any of the _THREADS options must normally also be defined in
+# the client before including gc.h.  This redefines thread primitives to
+# invoke the GC_ versions instead.  Alternatively, linker-based symbol
+# interception can be used on a few platforms.
+# -DGC_THREADS should set the appropriate one of the below macros,
+#   except -DGC_WIN32_PTHREADS, which must be set explicitly.
+# -DGC_SOLARIS_PTHREADS enables support for Solaris pthreads.
 #   (Clients should also define GC_SOLARIS_THREADS and then include
 #   gc.h before performing thr_ or dl* or GC_ operations.)
 #   Must also define -D_REENTRANT.
-# -DGC_SOLARIS_PTHREADS enables support for Solaris pthreads.
-#   (Internally this define GC_SOLARIS_THREADS as well.)
 # -DGC_IRIX_THREADS enables support for Irix pthreads.  See README.irix.
 # -DGC_HPUX_THREADS enables support for HP/UX 11 pthreads.
 #   Also requires -D_REENTRANT or -D_POSIX_C_SOURCE=199506L. See README.hp.
-# -DGC_LINUX_THREADS enables support for Xavier Leroy's Linux threads.
-#   see README.linux.  -D_REENTRANT may also be required.
+# -DGC_LINUX_THREADS enables support for Xavier Leroy's Linux threads
+#   or NPTL threads. See README.linux.  -D_REENTRANT may also be required.
 # -DGC_OSF1_THREADS enables support for Tru64 pthreads.
 # -DGC_FREEBSD_THREADS enables support for FreeBSD pthreads.
 #   Appeared to run into some underlying thread problems.
 # -DGC_DARWIN_THREADS enables support for Mac OS X pthreads.
 # -DGC_AIX_THREADS enables support for IBM AIX threads.
 # -DGC_DGUX386_THREADS enables support for DB/UX on I386 threads.
-#   See README.DGUX386.
+#   See README.DGUX386.  (Probably has not been tested recently.)
 # -DGC_WIN32_THREADS enables support for win32 threads.  That makes sense
 #   for this Makefile only under Cygwin.
-# -DGC_THREADS should set the appropriate one of the above macros.
-#   It assumes pthreads for Solaris.
+# -DGC_WIN32_PTHREADS enables support for Ming32 pthreads.  This cannot be
+#   enabled automatically by GC_THREADS, which would assume Win32 native
+#   threads.
+# -DPTW32_STATIC_LIB causes the static version of the Mingw pthreads library
+#   to be used.  Requires -DGC_WIN32_PTHREADS.
+#   
 # -DALL_INTERIOR_POINTERS allows all pointers to the interior
 #   of objects to be recognized.  (See gc_priv.h for consequences.)
 #   Alternatively, GC_all_interior_pointers can be set at process
index 218d903d4b026cb960f186540e5770122d756795..4e6f9d5bfa2b65082289e3b7f9935a5ed7777596 100644 (file)
@@ -196,6 +196,10 @@ Cygwin, use standard pthread calls instead.)  As in the pthread
 case, including gc.h will redefine CreateThread, _beginthreadex,
 _endthreadex, and ExitThread to call the GC_ versions instead.
 
+Note that, as usual, GC_CreateThread tends to introduce resource leaks
+that are avoided by GC_beginthreadex.  There is currently no equivalent of
+_beginthread, and it should not be used.
+
 GC_INIT should be called from the main executable before other GC calls.
 
 We strongly advise against using the TerminateThread() win32 API call,
@@ -203,3 +207,9 @@ especially with the garbage collector.  Any use is likely to provoke a
 crash in the GC, since it makes it impossible for the collector to
 correctly track threads.
 
+To build the collector for Mingw32 Pthreads, use Makefile.direct and
+explicitly set GC_WIN32_PTHREADS.  Use -DPTW32_STATIC_LIB for the static
+threads library.  Note that the DEBUG_WIN32_PTHREADS support in
+win32_threads.c is currently broken and looking for someone to debug it.
+(This information and the port came from Romano Paolo Tenca).
+
index 79aaeb409b732719388d9d7e69d91ca8b3b62c40..51659d1e8236fccb3ca44a394eccb6014f716698 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "private/gc_priv.h"
 
-# if (defined(GC_PTHREADS) && !defined(GC_DARWIN_THREADS)) \
+# if (defined(GC_PTHREADS) && !defined(GC_DARWIN_THREADS)) && !defined(GC_WIN32_PTHREADS)\
       || defined(GC_SOLARIS_THREADS)
 
 # if defined(dlopen) && !defined(GC_USE_LD_WRAP)
index f3d17d1afa6b6fdbf4622994d8010de41a6f2917..f3c7725b9cd51f118fcd4dea331ce2a701752c2b 100644 (file)
@@ -1003,7 +1003,8 @@ GC_register_has_static_roots_callback
   (int (*callback)(const char *, void *, size_t));
 
 
-#if defined(GC_WIN32_THREADS) && !defined(__CYGWIN32__) && !defined(__CYGWIN__)
+#if defined(GC_WIN32_THREADS) && !defined(__CYGWIN32__) && !defined(__CYGWIN__) \
+       && !defined(GC_PTHREADS)
 # include <windows.h>
 
   /*
index d73893f57b59c1fc7fe865646f179685ef1ce63a..4b37b1c7ba777aaba6d9e95745093d96af494859 100644 (file)
 #   define GC_PTHREADS
 # endif
 
+#if defined(GC_WIN32_PTHREADS)
+#   define GC_WIN32_THREADS
+#   define GC_PTHREADS
+#endif
+
 #if defined(GC_THREADS) && !defined(GC_PTHREADS)
 # if defined(__linux__)
 #   define GC_LINUX_THREADS
index de9e578ffe3d1ffe3b7e5a6d5448b9ea878e4955..8e23d9f43da7f4aede72387abe3f3283ebc4b4e8 100644 (file)
      /* the mapping to integers does not need to result in different   */
      /* integers for each thread, though that should be true as much   */
      /* as possible.                                                   */
-#    if 1 /* Refine to exclude platforms on which pthread_t is struct */
-#      define NUMERIC_THREAD_ID(id) ((unsigned long)(id))
-#      define THREAD_EQUAL(id1, id2) ((id1) == (id2))
-#       define NUMERIC_THREAD_ID_UNIQUE
+     /* Refine to exclude platforms on which pthread_t is struct */
+#    if !defined(GC_WIN32_PTHREADS)
+#      define NUMERIC_THREAD_ID(id) ((unsigned long)(id))
+#      define THREAD_EQUAL(id1, id2) ((id1) == (id2))
+#      define NUMERIC_THREAD_ID_UNIQUE
 #    else
-       /* Generic definitions that always work, but will result in     */
-       /* poor performance and weak assertion checking.                */
-#      define NUMERIC_THREAD_ID(id) 1l
-#      define THREAD_EQUAL(id1, id2) pthread_equal(id1, id2)
-#       undef NUMERIC_THREAD_ID_UNIQUE
+#      if defined(GC_WIN32_PTHREADS)
+#       define NUMERIC_THREAD_ID(id) ((unsigned long)(id.p))
+#       define THREAD_EQUAL(id1, id2) pthread_equal(id1, id2)
+#        undef NUMERIC_THREAD_ID_UNIQUE
+#      else
+        /* Generic definitions that always work, but will result in    */
+        /* poor performance and weak assertion checking.               */
+#       define NUMERIC_THREAD_ID(id) 1l
+#       define THREAD_EQUAL(id1, id2) pthread_equal(id1, id2)
+#        undef NUMERIC_THREAD_ID_UNIQUE
+#      endif
 #    endif
 #    define NO_THREAD (-1l)
                /* != NUMERIC_THREAD_ID(pthread_self()) for any thread */
index c3475b5719627b33dea69cb6194d475077d93e47..70bd7c5b3c818cfb5296076d64f191163e05eac6 100644 (file)
@@ -446,7 +446,7 @@ void check_marks_int_list(sexpr x)
  */
 #ifdef THREADS
 
-# if defined(GC_WIN32_THREADS) && !defined(CYGWIN32)
+# if defined(GC_WIN32_THREADS) && !defined(GC_PTHREADS)
     DWORD  __stdcall tiny_reverse_test(void * arg)
 # else
     void * tiny_reverse_test(void * arg)
@@ -1385,7 +1385,7 @@ void SetMinimumStack(long minSize)
 }
 # endif
 
-#if defined(GC_WIN32_THREADS) && !defined(CYGWIN32)
+#if defined(GC_WIN32_THREADS) && !defined(GC_PTHREADS)
 
 DWORD __stdcall thr_run_one_test(void *arg)
 {
@@ -1581,7 +1581,6 @@ int main()
     pthread_t th2;
     pthread_attr_t attr;
     int code;
-
 #   ifdef GC_IRIX_THREADS
        /* Force a larger stack to be preallocated      */
        /* Since the initial cant always grow later.    */
@@ -1594,6 +1593,10 @@ int main()
           (void)GC_printf("pthread_default_stacksize_np failed.\n");
        }
 #   endif      /* GC_HPUX_THREADS */
+#   ifdef PTW32_STATIC_LIB
+       pthread_win32_process_attach_np ();
+       pthread_win32_thread_attach_np ();
+#   endif
     GC_INIT();
 
     pthread_attr_init(&attr);
@@ -1644,6 +1647,10 @@ int main()
     (void)fflush(stdout);
     pthread_attr_destroy(&attr);
     GC_printf("Completed %d collections\n", GC_gc_no);
+#   ifdef PTW32_STATIC_LIB
+       pthread_win32_thread_detach_np ();
+       pthread_win32_process_detach_np ();
+#   endif
     return(0);
 }
 #endif /* GC_PTHREADS */
index 6c2bff3187370f63ee6f8075a0eb0544e9f60863..9acd3046db269df74398f6a14a7d23adb73032e5 100644 (file)
@@ -124,7 +124,8 @@ void GC_destroy_thread_local(GC_tlfs p)
 #   endif
 }
 
-#if defined(GC_ASSERTIONS) && defined(GC_PTHREADS) && !defined(CYGWIN32)
+#if defined(GC_ASSERTIONS) && defined(GC_PTHREADS) && !defined(CYGWIN32) \
+    && !defined(GC_WIN32_PTHREADS)
 # include <pthread.h>
   extern char * GC_lookup_thread(pthread_t id);
 #endif
index 50e962d17785a99a046e694d3497b2b3c8153fc9..f2ab58250f965cd3911bde3931b5d00f18b6a030 100644 (file)
@@ -42,6 +42,14 @@ int main()
 #   if defined(GC_WIN32_THREADS) && defined(CYGWIN32)
         printf("-lpthread\n");
 #   endif
+#   if defined(GC_WIN32_PTHREADS)
+#      ifdef PTW32_STATIC_LIB
+        /* assume suffix s for static version of the win32 pthread library */
+         printf("-lpthreadGC2s -lws2_32\n");
+#      else
+         printf("-lpthreadGC2\n");
+#      endif
+#   endif
 #   if defined(GC_OSF1_THREADS)
        printf("-pthread -lrt"); /* DOB: must be -pthread, not -lpthread */
 #   endif
index 41e4968c065f33452ae226f9753556cf22e661f1..85bce0ca5d2e4e3e104f61ee9f03ec941a676889 100644 (file)
@@ -29,7 +29,7 @@
   unsigned long GC_lock_holder = NO_THREAD;
 #endif
 
-#ifdef CYGWIN32
+#ifdef GC_PTHREADS
 # include <errno.h>
 
 /* GC_DLL should not normally be defined, especially since we often do turn on */
@@ -48,6 +48,7 @@
 # undef dlopen 
 
 # define DEBUG_CYGWIN_THREADS 0
+# define DEBUG_WIN32_PTHREADS 0
 
   void * GC_pthread_start(void * arg);
   void GC_thread_exit_proc(void *arg);
@@ -165,7 +166,7 @@ struct GC_Thread_Rep {
                        /* !in_use ==> stack_base == 0  */
   GC_bool suspended;
 
-# ifdef CYGWIN32
+# ifdef GC_PTHREADS
     void *status; /* hold exit value until join in case it's a pointer */
     pthread_t pthread_id;
     short flags;               /* Protected by GC lock.        */
@@ -255,7 +256,8 @@ GC_thread GC_new_thread(DWORD id)
         GC_ASSERT(!GC_win32_dll_threads);
         result = (struct GC_Thread_Rep *)
                 GC_INTERNAL_MALLOC(sizeof(struct GC_Thread_Rep), NORMAL);
-#       ifdef CYGWIN32
+#       ifdef GC_PTHREADS
+         /* result can be NULL -> segfault */
          GC_ASSERT(result -> flags == 0);
 #       endif
     }
@@ -263,7 +265,7 @@ GC_thread GC_new_thread(DWORD id)
     /* result -> id = id; Done by caller.      */
     result -> next = GC_threads[hv];
     GC_threads[hv] = result;
-#   ifdef CYGWIN32
+#   ifdef GC_PTHREADS
       GC_ASSERT(result -> flags == 0 /* && result -> thread_blocked == 0 */);
 #   endif
     return(result);
@@ -345,9 +347,11 @@ static GC_thread GC_register_my_thread_inner(struct GC_stack_base *sb,
     GC_ASSERT(I_HOLD_LOCK());
     me = GC_new_thread(thread_id);
   }
-# ifdef CYGWIN32
-    me -> pthread_id = pthread_self();
+# ifdef GC_PTHREADS
+  /* me can be NULL -> segfault */
+  me -> pthread_id = pthread_self();
 # endif
+
   if (!DuplicateHandle(GetCurrentProcess(),
                        GetCurrentThread(),
                        GetCurrentProcess(),
@@ -471,6 +475,9 @@ void GC_delete_gc_thread(GC_vthread gc_id)
 #   ifdef CYGWIN32
       gc_id -> pthread_id = 0;
 #   endif /* CYGWIN32 */
+#   ifdef GC_WIN32_PTHREADS
+      gc_id -> pthread_id.p = NULL;
+#   endif /* GC_WIN32_PTHREADS */
     AO_store_release(&(gc_id->in_use), FALSE);
   } else {
     /* Cast away volatile qualifier, since we have lock. */
@@ -567,7 +574,7 @@ int GC_unregister_my_thread(void)
 }
 
 
-#ifdef CYGWIN32
+#ifdef GC_PTHREADS
 
 /* A quick-and-dirty cache of the mapping between pthread_t    */
 /* and win32 thread id.                                                */
@@ -595,7 +602,7 @@ static GC_thread GC_lookup_pthread(pthread_t id)
     for (i = 0;
          i <= my_max &&
          (!AO_load_acquire(&(dll_thread_table[i].in_use))
-         || dll_thread_table[i].pthread_id != id);
+         || THREAD_EQUAL(dll_thread_table[i].pthread_id, id));
        /* Must still be in_use, since nobody else can store our thread_id. */
        i++);
     if (i > my_max) return 0;
@@ -625,7 +632,7 @@ static GC_thread GC_lookup_pthread(pthread_t id)
   }
 }
 
-#endif /* CYGWIN32 */
+#endif /* GC_PTHREADS */
 
 void GC_push_thread_structures(void)
 {
@@ -634,7 +641,7 @@ void GC_push_thread_structures(void)
     /* Unlike the other threads implementations, the thread table here */
     /* contains no pointers to the collectable heap.  Thus we have     */
     /* no private structures we need to preserve.                      */
-#   ifdef CYGWIN32
+#   ifdef GC_PTHREADS 
     { int i; /* pthreads may keep a pointer in the thread exit value */
       LONG my_max = GC_get_max_thread_index();
 
@@ -671,7 +678,7 @@ void GC_suspend(GC_thread t)
     if (GetExitCodeThread(t -> handle, &exitCode) &&
         exitCode != STILL_ACTIVE) {
       t -> stack_base = 0; /* prevent stack from being pushed */
-#     ifndef CYGWIN32
+#     ifndef GC_PTHREADS
         /* this breaks pthread_join on Cygwin, which is guaranteed to  */
         /* only see user pthreads                                     */
         AO_store(&(t -> in_use), FALSE);
@@ -686,7 +693,7 @@ void GC_suspend(GC_thread t)
 }
 
 /* Defined in misc.c */
-#ifndef CYGWIN32
+#ifndef GC_PTHREADS
   extern CRITICAL_SECTION GC_write_cs;
 #endif
 
@@ -699,7 +706,7 @@ void GC_stop_world(void)
   GC_ASSERT(I_HOLD_LOCK());
 
   GC_please_stop = TRUE;
-# ifndef CYGWIN32
+# ifndef GC_PTHREADS
     EnterCriticalSection(&GC_write_cs);
 # endif
   if (GC_win32_dll_threads) {
@@ -728,7 +735,7 @@ void GC_stop_world(void)
        }
       }
   }
-# ifndef CYGWIN32
+# ifndef GC_PTHREADS
     LeaveCriticalSection(&GC_write_cs);
 # endif    
 }
@@ -849,6 +856,10 @@ void GC_push_stack_for(GC_thread thread)
 #       if DEBUG_CYGWIN_THREADS
          GC_printf("Pushing thread from %p to %p for %d from %d\n",
                    sp, thread -> stack_base, thread -> id, me);
+#       endif
+#       if DEBUG_WIN32_PTHREADS
+         GC_printf("Pushing thread from %p to %p for 0x%x from 0x%x\n",
+                   sp, thread -> stack_base, thread -> id, me);
 #       endif
         GC_push_all_stack(sp, thread->stack_base);
       } else {
@@ -938,7 +949,7 @@ void GC_get_next_stack(char *start, char **lo, char **hi)
     if (*lo < start) *lo = start;
 }
 
-#if !defined(CYGWIN32)
+#ifndef GC_PTHREADS
 
 /* We have no DllMain to take care of new threads.  Thus we    */
 /* must properly intercept thread creation.                    */
@@ -1067,7 +1078,7 @@ void GC_endthreadex(unsigned retval)
   _endthreadex(retval);
 }
 
-#endif /* !CYGWIN32 */
+#endif /* !GC_PTHREADS */
 
 #ifdef MSWINCE
 
@@ -1137,7 +1148,7 @@ void GC_thr_init(void) {
     GC_register_my_thread(&sb);
 }
 
-#ifdef CYGWIN32
+#ifdef GC_PTHREADS
 
 struct start_info {
     void *(*start_routine)(void *);
@@ -1154,6 +1165,10 @@ int GC_pthread_join(pthread_t pthread_id, void **retval) {
       GC_printf("thread 0x%x(0x%x) is joining thread 0x%x.\n",
                (int)pthread_self(), GetCurrentThreadId(), (int)pthread_id);
 #   endif
+#   if DEBUG_WIN32_PTHREADS
+      GC_printf("thread 0x%x(0x%x) is joining thread 0x%x.\n",
+               (pthread_self()).p, GetCurrentThreadId(), pthread_id.p);
+#   endif
 
     if (!parallel_initialized) GC_init_parallel();
     /* Thread being joined might not have registered itself yet. */
@@ -1175,6 +1190,10 @@ int GC_pthread_join(pthread_t pthread_id, void **retval) {
       GC_printf("thread 0x%x(0x%x) completed join with thread 0x%x.\n",
                 (int)pthread_self(), GetCurrentThreadId(), (int)pthread_id);
 #   endif
+#   if DEBUG_WIN32_PTHREADS
+      GC_printf("thread 0x%x(0x%x) completed join with thread 0x%x.\n",
+               (pthread_self()).p, GetCurrentThreadId(), pthread_id.p);
+#   endif
 
     return result;
 }
@@ -1212,6 +1231,10 @@ GC_pthread_create(pthread_t *new_thread,
 #   if DEBUG_CYGWIN_THREADS
       GC_printf("About to create a thread from 0x%x(0x%x)\n",
                (int)pthread_self(), GetCurrentThreadId);
+#   endif
+#   if DEBUG_WIN32_PTHREADS
+      GC_printf("About to create a thread from 0x%x(0x%x)\n",
+               (pthread_self()).p, GetCurrentThreadId());
 #   endif
     GC_need_to_lock = TRUE;
     result = pthread_create(new_thread, attr, GC_pthread_start, si); 
@@ -1239,6 +1262,10 @@ void * GC_pthread_start_inner(struct GC_stack_base *sb, void * arg)
       GC_printf("thread 0x%x(0x%x) starting...\n",(int)pthread_id,
                                                  thread_id);
 #   endif
+#   if DEBUG_WIN32_PTHREADS
+      GC_printf("thread 0x%x(0x%x) starting...\n",(int) pthread_id.p,
+                                                 thread_id);
+#   endif
 
     GC_ASSERT(!GC_win32_dll_threads);
     /* If a GC occurs before the thread is registered, that GC will    */
@@ -1268,6 +1295,10 @@ void * GC_pthread_start_inner(struct GC_stack_base *sb, void * arg)
       GC_printf("thread 0x%x(0x%x) returned from start routine.\n",
                (int)pthread_self(),GetCurrentThreadId());
 #   endif
+#   if DEBUG_WIN32_PTHREADS
+      GC_printf("thread 0x%x(0x%x) returned from start routine.\n",
+               (int)(pthread_self()).p, GetCurrentThreadId());
+#   endif
 
     return(result);
 }
@@ -1287,6 +1318,10 @@ void GC_thread_exit_proc(void *arg)
       GC_printf("thread 0x%x(0x%x) called pthread_exit().\n",
                (int)pthread_self(),GetCurrentThreadId());
 #   endif
+#   if DEBUG_WIN32_PTHREADS
+      GC_printf("thread 0x%x(0x%x) called pthread_exit().\n",
+               (int)(pthread_self()).p,GetCurrentThreadId());
+#   endif
 
     LOCK();
 #   if defined(THREAD_LOCAL_ALLOC)
@@ -1301,11 +1336,14 @@ void GC_thread_exit_proc(void *arg)
     UNLOCK();
 }
 
+#ifndef GC_WIN32_PTHREADS
+/* win32 pthread does not support sigmask */
 /* nothing required here... */
 int GC_pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) {
   if (!parallel_initialized) GC_init_parallel();
   return pthread_sigmask(how, set, oset);
 }
+#endif
 
 int GC_pthread_detach(pthread_t thread)
 {
@@ -1329,7 +1367,7 @@ int GC_pthread_detach(pthread_t thread)
     return result;
 }
 
-#else /* !CYGWIN32 */
+#else /* !GC_PTHREADS */
 
 /*
  * We avoid acquiring locks here, since this doesn't seem to be preemptable.
@@ -1394,7 +1432,7 @@ GC_API BOOL WINAPI DllMain(HINSTANCE inst, ULONG reason, LPVOID reserved)
   return TRUE;
 }
 #endif /* GC_DLL */
-#endif /* !CYGWIN32 */
+#endif /* !GC_PTHREADS */
 
 # endif /* !MSWINCE */