[Gc] win32_pthreads

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",