[Gc] win32_pthreads

Romano Paolo Tenca rotenca at telvia.it
Tue May 22 17:27:20 PDT 2007


Boehm, Hans ha scritto:
> Could you resend the patch as an attachment?  Some mail software managed
> to add line breaks ...
>
>   
Here it is.

-- 

Romano Paolo Tenca

-------------- next part --------------
Index: gc_dlopen.c
===================================================================
RCS file: /cvsroot/bdwgc/bdwgc/gc_dlopen.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 gc_dlopen.c
--- gc_dlopen.c	10 Oct 2005 22:33:34 -0000	1.1.1.1
+++ gc_dlopen.c	19 May 2007 17:03:55 -0000
@@ -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: thread_local_alloc.c
===================================================================
RCS file: /cvsroot/bdwgc/bdwgc/thread_local_alloc.c,v
retrieving revision 1.8
diff -u -r1.8 thread_local_alloc.c
--- thread_local_alloc.c	11 May 2007 21:55:38 -0000	1.8
+++ thread_local_alloc.c	19 May 2007 19:29:04 -0000
@@ -124,7 +124,8 @@
 #   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: threadlibs.c
===================================================================
RCS file: /cvsroot/bdwgc/bdwgc/threadlibs.c,v
retrieving revision 1.4
diff -u -r1.4 threadlibs.c
--- threadlibs.c	17 Nov 2006 05:28:22 -0000	1.4
+++ threadlibs.c	21 May 2007 19:57:43 -0000
@@ -42,6 +42,14 @@
 #   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: win32_threads.c
===================================================================
RCS file: /cvsroot/bdwgc/bdwgc/win32_threads.c,v
retrieving revision 1.8
diff -u -r1.8 win32_threads.c
--- win32_threads.c	15 May 2007 18:57:48 -0000	1.8
+++ win32_threads.c	22 May 2007 14:23:27 -0000
@@ -2,7 +2,7 @@
 
 #if defined(GC_WIN32_THREADS) 
 
-#if defined( _MINGW_VER )
+#if defined( _MINGW_VER ) || defined(__MINGW32__)
 # include <stdint.h>
 	/* We mention uintptr_t.					*/
 	/* Perhaps this should be included in pure msft environments	*/
@@ -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 @@
 			/* !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_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 @@
     /* 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 @@
     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 @@
 #   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 @@
 }
 
 
-#ifdef CYGWIN32
+#ifdef GC_PTHREADS
 
 /* A quick-and-dirty cache of the mapping between pthread_t	*/
 /* and win32 thread id.						*/
@@ -595,7 +602,7 @@
     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 @@
   }
 }
 
-#endif /* CYGWIN32 */
+#endif /* GC_PTHREADS */
 
 void GC_push_thread_structures(void)
 {
@@ -634,7 +641,7 @@
     /* 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 @@
     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 @@
 }
 
 /* Defined in misc.c */
-#ifndef CYGWIN32
+#ifndef GC_PTHREADS
   extern CRITICAL_SECTION GC_write_cs;
 #endif
 
@@ -699,7 +706,7 @@
   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 @@
 	}
       }
   }
-# ifndef CYGWIN32
+# ifndef GC_PTHREADS
     LeaveCriticalSection(&GC_write_cs);
 # endif    
 }
@@ -850,6 +857,10 @@
 	  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 {
         WARN("Thread stack pointer 0x%lx out of range, pushing everything\n",
@@ -938,7 +949,7 @@
     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 @@
   _endthreadex(retval);
 }
 
-#endif /* !CYGWIN32 */
+#endif /* !GC_PTHREADS */
 
 #ifdef MSWINCE
 
@@ -1137,7 +1148,7 @@
     GC_register_my_thread(&sb);
 }
 
-#ifdef CYGWIN32
+#ifdef GC_PTHREADS
 
 struct start_info {
     void *(*start_routine)(void *);
@@ -1154,6 +1165,10 @@
       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 @@
       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;
 }
@@ -1213,6 +1232,10 @@
       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 @@
       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 @@
       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 @@
       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 @@
     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 @@
     return result;
 }
 
-#else /* !CYGWIN32 */
+#else /* !GC_PTHREADS */
 
 /*
  * We avoid acquiring locks here, since this doesn't seem to be preemptable.
@@ -1394,7 +1432,7 @@
   return TRUE;
 }
 #endif /* GC_DLL */
-#endif /* !CYGWIN32 */
+#endif /* !GC_PTHREADS */
 
 # endif /* !MSWINCE */
 
Index: include/gc.h
===================================================================
RCS file: /cvsroot/bdwgc/bdwgc/include/gc.h,v
retrieving revision 1.14
diff -u -r1.14 gc.h
--- include/gc.h	11 May 2007 21:55:38 -0000	1.14
+++ include/gc.h	19 May 2007 22:12:48 -0000
@@ -986,7 +986,8 @@
   (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: include/gc_config_macros.h
===================================================================
RCS file: /cvsroot/bdwgc/bdwgc/include/gc_config_macros.h,v
retrieving revision 1.7
diff -u -r1.7 gc_config_macros.h
--- include/gc_config_macros.h	11 May 2007 00:30:36 -0000	1.7
+++ include/gc_config_macros.h	19 May 2007 17:03:55 -0000
@@ -69,6 +69,11 @@
 #   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: include/private/gc_locks.h
===================================================================
RCS file: /cvsroot/bdwgc/bdwgc/include/private/gc_locks.h,v
retrieving revision 1.7
diff -u -r1.7 gc_locks.h
--- include/private/gc_locks.h	15 May 2007 18:57:48 -0000	1.7
+++ include/private/gc_locks.h	21 May 2007 15:58:52 -0000
@@ -81,16 +81,23 @@
      /* 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: tests/test.c
===================================================================
RCS file: /cvsroot/bdwgc/bdwgc/tests/test.c,v
retrieving revision 1.5
diff -u -r1.5 test.c
--- tests/test.c	20 Sep 2006 01:08:14 -0000	1.5
+++ tests/test.c	21 May 2007 19:52:18 -0000
@@ -446,7 +446,7 @@
  */
 #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)
@@ -1384,7 +1384,7 @@
 }
 # endif
 
-#if defined(GC_WIN32_THREADS) && !defined(CYGWIN32)
+#if defined(GC_WIN32_THREADS) && !defined(GC_PTHREADS)
 
 DWORD __stdcall thr_run_one_test(void *arg)
 {
@@ -1580,7 +1580,6 @@
     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.	*/
@@ -1593,6 +1592,10 @@
           (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);
@@ -1643,6 +1646,10 @@
     (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 */


More information about the Gc mailing list