2007-06-06 Hans Boehm <Hans.Boehm@hp.com> (Really mostly Romano Paolo Tenca)
authorhboehm <hboehm>
Wed, 6 Jun 2007 19:29:05 +0000 (19:29 +0000)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 26 Jul 2011 17:06:40 +0000 (21:06 +0400)
* win32_threads.c: Separate out DEBUG_WIN32_PTHREADS_STACK.  Ignore
FINISHED threads for suspension.  (GC_pthread_join): Add
pthread_self() cast.  (GC_pthread_start_inner): Execute cleanup
handler when popping it.
* include/private/gc_locks.h: Inline THREAD_EQUAL for
GC_WIN32_PTHREADS.  Define USE_PTHREAD_LOCKS only if we have
pthreads.

ChangeLog
include/private/gc_locks.h
win32_threads.c

index e0ab547..2f1f7fa 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2007-06-06  Hans Boehm <Hans.Boehm@hp.com> (Really mostly Romano Paolo Tenca)
+       * win32_threads.c: Separate out DEBUG_WIN32_PTHREADS_STACK.  Ignore
+       FINISHED threads for suspension.  (GC_pthread_join): Add
+       pthread_self() cast.  (GC_pthread_start_inner): Execute cleanup
+       handler when popping it.
+       * include/private/gc_locks.h: Inline THREAD_EQUAL for
+       GC_WIN32_PTHREADS.  Define USE_PTHREAD_LOCKS only if we have
+       pthreads.
+
 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,
index 8e23d9f..d7c83b0 100644 (file)
@@ -40,7 +40,7 @@
 #    define UNLOCK() PCR_Th_ML_Release(&GC_allocate_ml)
 #  endif
 
-#  if !defined(AO_HAVE_test_and_set_acquire)
+#  if !defined(AO_HAVE_test_and_set_acquire) && defined(GC_PTHREADS)
 #    define USE_PTHREAD_LOCKS
 #  endif
 
 #    else
 #      if defined(GC_WIN32_PTHREADS)
 #       define NUMERIC_THREAD_ID(id) ((unsigned long)(id.p))
-#       define THREAD_EQUAL(id1, id2) pthread_equal(id1, id2)
+        /* Using documented internal details of win32_pthread library. */
+        /* Faster than pthread_equal(). Should not change with         */
+        /* future versions of win32_pthread library.                   */
+#       define THREAD_EQUAL(id1, id2) ((id1.p == id2.p) && (id1.x == id2.x))
 #        undef NUMERIC_THREAD_ID_UNIQUE
 #      else
         /* Generic definitions that always work, but will result in    */
index 85bce0c..c89d972 100644 (file)
 #ifdef GC_PTHREADS
 # include <errno.h>
 
-/* GC_DLL should not normally be defined, especially since we often do turn on */
-/* THREAD_LOCAL_ALLOC, which is currently incompatible.                        */
-/* It might be possible to get GC_DLL and DllMain-based        thread registration to  */
-/* work with Cygwin, but if you try you are on your own.                       */
+/* GC_DLL should not normally be defined, especially since we often do turn */
+/* on THREAD_LOCAL_ALLOC, which is currently incompatible.                 */
+/* It might be possible to get GC_DLL and DllMain-based        thread registration */
+/* to work with Cygwin, but if you try you are on your own.                */
 #ifdef GC_DLL
 # error GC_DLL untested with Cygwin
 #endif
 
 # define DEBUG_CYGWIN_THREADS 0
 # define DEBUG_WIN32_PTHREADS 0
+# define DEBUG_WIN32_PTHREADS_STACK 0
+
+# if DEBUG_WIN32_PTHREADS_STACK
+    /* It seems that is not safe to call GC_printf() if any threads  */
+    /* are suspended while executing GC_printf().                    */
+#   define DEBUG_WIN32_PTHREADS 0
+# endif  
 
   void * GC_pthread_start(void * arg);
   void GC_thread_exit_proc(void *arg);
@@ -60,6 +67,7 @@
 # undef CreateThread
 # undef ExitThread
 # undef _beginthreadex
+# undef _beginthread
 # undef _endthreadex
 # include <process.h>  /* For _beginthreadex, _endthreadex */
 
@@ -172,6 +180,9 @@ struct GC_Thread_Rep {
     short flags;               /* Protected by GC lock.        */
 #      define FINISHED 1       /* Thread has exited.   */
 #      define DETACHED 2       /* Thread is intended to be detached.   */
+#   define KNOWN_FINISHED(t) (((t) -> flags) & FINISHED)
+# else
+#   define KNOWN_FINISHED(t) 0
 # endif
 # ifdef THREAD_LOCAL_ALLOC
     struct thread_local_freelists tlfs;
@@ -729,6 +740,7 @@ void GC_stop_world(void)
       for (i = 0; i < THREAD_TABLE_SZ; i++) {
         for (t = GC_threads[i]; t != 0; t = t -> next) {
          if (t -> stack_base != 0
+         && !KNOWN_FINISHED(t)
          && t -> id != thread_id) {
            GC_suspend(t);
          }
@@ -857,7 +869,7 @@ void GC_push_stack_for(GC_thread thread)
          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
+#       if DEBUG_WIN32_PTHREADS_STACK
          GC_printf("Pushing thread from %p to %p for 0x%x from 0x%x\n",
                    sp, thread -> stack_base, thread -> id, me);
 #       endif
@@ -895,7 +907,7 @@ void GC_push_all_stacks(void)
     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 (!KNOWN_FINISHED(t)) GC_push_stack_for(t);
         if (t -> id == me) found_me = TRUE;
       }
     }
@@ -1167,7 +1179,7 @@ int GC_pthread_join(pthread_t pthread_id, void **retval) {
 #   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);
+               (int)(pthread_self()).p, GetCurrentThreadId(), pthread_id.p);
 #   endif
 
     if (!parallel_initialized) GC_init_parallel();
@@ -1176,10 +1188,17 @@ int GC_pthread_join(pthread_t pthread_id, void **retval) {
     /* FIXME: It would be better if this worked more like       */
     /* pthread_support.c.                                       */
 
-    while ((joinee = GC_lookup_pthread(pthread_id)) == 0) Sleep(10);
+    #ifndef GC_WIN32_PTHREADS
+      while ((joinee = GC_lookup_pthread(pthread_id)) == 0) Sleep(10);
+    #endif
 
     result = pthread_join(pthread_id, retval);
 
+    #ifdef GC_WIN32_PTHREADS
+      /* win32_pthreads id are unique */
+      joinee = GC_lookup_pthread(pthread_id);
+    #endif
+
     if (!GC_win32_dll_threads) {
       LOCK();
       GC_delete_gc_thread(joinee);
@@ -1192,7 +1211,7 @@ int GC_pthread_join(pthread_t pthread_id, void **retval) {
 #   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);
+               (int)(pthread_self()).p, GetCurrentThreadId(), pthread_id.p);
 #   endif
 
     return result;
@@ -1234,7 +1253,7 @@ GC_pthread_create(pthread_t *new_thread,
 #   endif
 #   if DEBUG_WIN32_PTHREADS
       GC_printf("About to create a thread from 0x%x(0x%x)\n",
-               (pthread_self()).p, GetCurrentThreadId());
+               (int)(pthread_self()).p, GetCurrentThreadId());
 #   endif
     GC_need_to_lock = TRUE;
     result = pthread_create(new_thread, attr, GC_pthread_start, si); 
@@ -1289,7 +1308,7 @@ void * GC_pthread_start_inner(struct GC_stack_base *sb, void * arg)
     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",