[Gc] win32_pthreads

Romano Paolo Tenca rotenca at telvia.it
Thu May 24 13:23:02 PDT 2007


I have understood (i hope) why the win32 pthread implementation fails 
when the debug options are active.

I think to have found two problems in the GC pthread implementation:

1) In GC_pthread_start_inner() the line:

     pthread_cleanup_pop(0);

 should be:

     pthread_cleanup_pop(1);

else the routine GC_thread_exit_proc () is not called. Another solution 
is to put the same code of GC_thread_exit_proc() in 
GC_pthread_start_inner().
This should be a problem also under Cygwin.

2) Under win32_pthread and Mingw (also under Cygwin?) a joinable thread 
which has completed its code and is ready to be joined cannot be 
suspended with native Windows SuspendThread() (the pthread library has 
already called _endthread), so GC_stop_world() will fail.
And if a thread is not in suspended mode, GetThreadContext() cannot be 
called by GC_push_stack_for().

Probably there are different solutions to this problem. One of them 
could be to check the FINISHED flags set by GC_thread_exit_proc(), if 
the flags is set the thread should be ignored by GC_stop_world() and by 
GC_push_stack_for().

With these changes, gctest works a lot better whith debug flag. It hangs 
only if GC_printf is called from GC_push_stack_for(). I can't explain 
why. :-(

See my patch.

-- 
Romano Paolo Tenca

-------------- next part --------------
Index: win32_threads.c
===================================================================
RCS file: /cvsroot/bdwgc/bdwgc/win32_threads.c,v
retrieving revision 1.10
diff -u -r1.10 win32_threads.c
--- win32_threads.c	24 May 2007 05:18:06 -0000	1.10
+++ win32_threads.c	24 May 2007 20:12:27 -0000
@@ -729,6 +729,7 @@
       for (i = 0; i < THREAD_TABLE_SZ; i++) {
         for (t = GC_threads[i]; t != 0; t = t -> next) {
 	  if (t -> stack_base != 0
+	  && !(t -> flags & FINISHED)
 	  && t -> id != thread_id) {
 	    GC_suspend(t);
 	  }
@@ -895,7 +896,7 @@
     for (i = 0; i < THREAD_TABLE_SZ; i++) {
       for (t = GC_threads[i]; t != 0; t = t -> next) {
         ++nthreads;
-        GC_push_stack_for(t);
+        if (!(t -> flags & FINISHED)) GC_push_stack_for(t);
         if (t -> id == me) found_me = TRUE;
       }
     }
@@ -1289,7 +1290,7 @@
     pthread_cleanup_push(GC_thread_exit_proc, (void *)me);
     result = (*start)(start_arg);
     me -> status = result;
-    pthread_cleanup_pop(0);
+    pthread_cleanup_pop(1);
 
 #   if DEBUG_CYGWIN_THREADS
       GC_printf("thread 0x%x(0x%x) returned from start routine.\n",


More information about the Gc mailing list