From: Bruno Haible Date: Thu, 9 Jun 2011 10:40:44 +0000 (+0200) Subject: thread: Support pthreads-win32. X-Git-Tag: v0.1~2625 X-Git-Url: http://erislabs.org.uk/gitweb/?a=commitdiff_plain;h=f462d86108d41b1ca0f48b51caad6c696d67d8fd;p=gnulib.git thread: Support pthreads-win32. * lib/glthread/thread.h (gl_thread_self): Define differently on pthreads-win32. (gl_null_thread): New declaration. (gl_thread_self_pointer): New macro. * lib/glthread/thread.c (gl_null_thread): New constant. * tests/test-lock.c: Use gl_thread_self_pointer instead of gl_thread_self. * tests/test-tls.c: Likewise. Suggested by Paul Eggert. Reported by Eric Blake. --- diff --git a/ChangeLog b/ChangeLog index 57813f105..69e4e0364 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,18 @@ 2011-06-09 Bruno Haible + thread: Support pthreads-win32. + * lib/glthread/thread.h (gl_thread_self): Define differently on + pthreads-win32. + (gl_null_thread): New declaration. + (gl_thread_self_pointer): New macro. + * lib/glthread/thread.c (gl_null_thread): New constant. + * tests/test-lock.c: Use gl_thread_self_pointer instead of + gl_thread_self. + * tests/test-tls.c: Likewise. + Suggested by Paul Eggert. Reported by Eric Blake. + +2011-06-09 Bruno Haible + thread: Fix confusion between NULL and 0. * lib/glthread/thread.h (gl_thread_self): Use NULL and 0 appropriately. Reported by Paul Eggert. diff --git a/lib/glthread/thread.c b/lib/glthread/thread.c index 6b134a707..d6af6f35f 100644 --- a/lib/glthread/thread.c +++ b/lib/glthread/thread.c @@ -29,6 +29,20 @@ /* ========================================================================= */ +#if USE_POSIX_THREADS + +#include + +#ifdef PTW32_VERSION + +const gl_thread_t gl_null_thread /* = { .p = NULL } */; + +#endif + +#endif + +/* ========================================================================= */ + #if USE_WIN32_THREADS #include diff --git a/lib/glthread/thread.h b/lib/glthread/thread.h index a0d40f8eb..82975bf16 100644 --- a/lib/glthread/thread.h +++ b/lib/glthread/thread.h @@ -47,6 +47,10 @@ current = gl_thread_self (); extern gl_thread_t gl_thread_self (void); + Getting a reference to the current thread as a pointer, for debugging: + ptr = gl_thread_self_pointer (); + extern void * gl_thread_self_pointer (void); + Terminating the current thread: gl_thread_exit (return_value); extern void gl_thread_exit (void *return_value) __attribute__ ((noreturn)); @@ -147,8 +151,20 @@ typedef pthread_t gl_thread_t; (pthread_in_use () ? pthread_sigmask (HOW, SET, OSET) : 0) # define glthread_join(THREAD, RETVALP) \ (pthread_in_use () ? pthread_join (THREAD, RETVALP) : 0) -# define gl_thread_self() \ - (pthread_in_use () ? (void *) pthread_self () : NULL) +# ifdef PTW32_VERSION + /* In pthreads-win32, pthread_t is a struct with a pointer field 'p' and + other fields. */ +# define gl_thread_self() \ + (pthread_in_use () ? pthread_self () : gl_null_thread) +# define gl_thread_self_pointer() \ + (pthread_in_use () ? pthread_self ().p : NULL) +extern const gl_thread_t gl_null_thread; +# else +# define gl_thread_self() \ + (pthread_in_use () ? (void *) pthread_self () : NULL) +# define gl_thread_self_pointer() \ + gl_thread_self () +# endif # define gl_thread_exit(RETVAL) \ (pthread_in_use () ? pthread_exit (RETVAL) : 0) @@ -206,6 +222,8 @@ typedef pth_t gl_thread_t; (pth_in_use () && !pth_join (THREAD, RETVALP) ? errno : 0) # define gl_thread_self() \ (pth_in_use () ? (void *) pth_self () : NULL) +# define gl_thread_self_pointer() \ + gl_thread_self () # define gl_thread_exit(RETVAL) \ (pth_in_use () ? pth_exit (RETVAL) : 0) # define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) 0 @@ -258,6 +276,8 @@ typedef thread_t gl_thread_t; (thread_in_use () ? thr_join (THREAD, NULL, RETVALP) : 0) # define gl_thread_self() \ (thread_in_use () ? (void *) thr_self () : NULL) +# define gl_thread_self_pointer() \ + gl_thread_self () # define gl_thread_exit(RETVAL) \ (thread_in_use () ? thr_exit (RETVAL) : 0) # define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) 0 @@ -298,6 +318,8 @@ typedef struct gl_thread_struct *gl_thread_t; glthread_join_func (THREAD, RETVALP) # define gl_thread_self() \ gl_thread_self_func () +# define gl_thread_self_pointer() \ + gl_thread_self () # define gl_thread_exit(RETVAL) \ gl_thread_exit_func (RETVAL) # define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) 0 @@ -323,6 +345,8 @@ typedef int gl_thread_t; # define glthread_sigmask(HOW, SET, OSET) 0 # define glthread_join(THREAD, RETVALP) 0 # define gl_thread_self() 0 +# define gl_thread_self_pointer() \ + ((void *) gl_thread_self ()) # define gl_thread_exit(RETVAL) 0 # define glthread_atfork(PREPARE_FUNC, PARENT_FUNC, CHILD_FUNC) 0 diff --git a/tests/test-lock.c b/tests/test-lock.c index 04ce0767f..3f8846bc2 100644 --- a/tests/test-lock.c +++ b/tests/test-lock.c @@ -143,9 +143,9 @@ lock_mutator_thread (void *arg) { int i1, i2, value; - dbgprintf ("Mutator %p before lock\n", gl_thread_self ()); + dbgprintf ("Mutator %p before lock\n", gl_thread_self_pointer ()); gl_lock_lock (my_lock); - dbgprintf ("Mutator %p after lock\n", gl_thread_self ()); + dbgprintf ("Mutator %p after lock\n", gl_thread_self_pointer ()); i1 = random_account (); i2 = random_account (); @@ -153,20 +153,20 @@ lock_mutator_thread (void *arg) account[i1] += value; account[i2] -= value; - dbgprintf ("Mutator %p before unlock\n", gl_thread_self ()); + dbgprintf ("Mutator %p before unlock\n", gl_thread_self_pointer ()); gl_lock_unlock (my_lock); - dbgprintf ("Mutator %p after unlock\n", gl_thread_self ()); + dbgprintf ("Mutator %p after unlock\n", gl_thread_self_pointer ()); - dbgprintf ("Mutator %p before check lock\n", gl_thread_self ()); + dbgprintf ("Mutator %p before check lock\n", gl_thread_self_pointer ()); gl_lock_lock (my_lock); check_accounts (); gl_lock_unlock (my_lock); - dbgprintf ("Mutator %p after check unlock\n", gl_thread_self ()); + dbgprintf ("Mutator %p after check unlock\n", gl_thread_self_pointer ()); yield (); } - dbgprintf ("Mutator %p dying.\n", gl_thread_self ()); + dbgprintf ("Mutator %p dying.\n", gl_thread_self_pointer ()); return NULL; } @@ -177,16 +177,16 @@ lock_checker_thread (void *arg) { while (!lock_checker_done) { - dbgprintf ("Checker %p before check lock\n", gl_thread_self ()); + dbgprintf ("Checker %p before check lock\n", gl_thread_self_pointer ()); gl_lock_lock (my_lock); check_accounts (); gl_lock_unlock (my_lock); - dbgprintf ("Checker %p after check unlock\n", gl_thread_self ()); + dbgprintf ("Checker %p after check unlock\n", gl_thread_self_pointer ()); yield (); } - dbgprintf ("Checker %p dying.\n", gl_thread_self ()); + dbgprintf ("Checker %p dying.\n", gl_thread_self_pointer ()); return NULL; } @@ -233,9 +233,9 @@ rwlock_mutator_thread (void *arg) { int i1, i2, value; - dbgprintf ("Mutator %p before wrlock\n", gl_thread_self ()); + dbgprintf ("Mutator %p before wrlock\n", gl_thread_self_pointer ()); gl_rwlock_wrlock (my_rwlock); - dbgprintf ("Mutator %p after wrlock\n", gl_thread_self ()); + dbgprintf ("Mutator %p after wrlock\n", gl_thread_self_pointer ()); i1 = random_account (); i2 = random_account (); @@ -243,14 +243,14 @@ rwlock_mutator_thread (void *arg) account[i1] += value; account[i2] -= value; - dbgprintf ("Mutator %p before unlock\n", gl_thread_self ()); + dbgprintf ("Mutator %p before unlock\n", gl_thread_self_pointer ()); gl_rwlock_unlock (my_rwlock); - dbgprintf ("Mutator %p after unlock\n", gl_thread_self ()); + dbgprintf ("Mutator %p after unlock\n", gl_thread_self_pointer ()); yield (); } - dbgprintf ("Mutator %p dying.\n", gl_thread_self ()); + dbgprintf ("Mutator %p dying.\n", gl_thread_self_pointer ()); return NULL; } @@ -261,16 +261,16 @@ rwlock_checker_thread (void *arg) { while (!rwlock_checker_done) { - dbgprintf ("Checker %p before check rdlock\n", gl_thread_self ()); + dbgprintf ("Checker %p before check rdlock\n", gl_thread_self_pointer ()); gl_rwlock_rdlock (my_rwlock); check_accounts (); gl_rwlock_unlock (my_rwlock); - dbgprintf ("Checker %p after check unlock\n", gl_thread_self ()); + dbgprintf ("Checker %p after check unlock\n", gl_thread_self_pointer ()); yield (); } - dbgprintf ("Checker %p dying.\n", gl_thread_self ()); + dbgprintf ("Checker %p dying.\n", gl_thread_self_pointer ()); return NULL; } @@ -315,9 +315,9 @@ recshuffle (void) { int i1, i2, value; - dbgprintf ("Mutator %p before lock\n", gl_thread_self ()); + dbgprintf ("Mutator %p before lock\n", gl_thread_self_pointer ()); gl_recursive_lock_lock (my_reclock); - dbgprintf ("Mutator %p after lock\n", gl_thread_self ()); + dbgprintf ("Mutator %p after lock\n", gl_thread_self_pointer ()); i1 = random_account (); i2 = random_account (); @@ -329,9 +329,9 @@ recshuffle (void) if (((unsigned int) rand () >> 3) % 2) recshuffle (); - dbgprintf ("Mutator %p before unlock\n", gl_thread_self ()); + dbgprintf ("Mutator %p before unlock\n", gl_thread_self_pointer ()); gl_recursive_lock_unlock (my_reclock); - dbgprintf ("Mutator %p after unlock\n", gl_thread_self ()); + dbgprintf ("Mutator %p after unlock\n", gl_thread_self_pointer ()); } static void * @@ -343,16 +343,16 @@ reclock_mutator_thread (void *arg) { recshuffle (); - dbgprintf ("Mutator %p before check lock\n", gl_thread_self ()); + dbgprintf ("Mutator %p before check lock\n", gl_thread_self_pointer ()); gl_recursive_lock_lock (my_reclock); check_accounts (); gl_recursive_lock_unlock (my_reclock); - dbgprintf ("Mutator %p after check unlock\n", gl_thread_self ()); + dbgprintf ("Mutator %p after check unlock\n", gl_thread_self_pointer ()); yield (); } - dbgprintf ("Mutator %p dying.\n", gl_thread_self ()); + dbgprintf ("Mutator %p dying.\n", gl_thread_self_pointer ()); return NULL; } @@ -363,16 +363,16 @@ reclock_checker_thread (void *arg) { while (!reclock_checker_done) { - dbgprintf ("Checker %p before check lock\n", gl_thread_self ()); + dbgprintf ("Checker %p before check lock\n", gl_thread_self_pointer ()); gl_recursive_lock_lock (my_reclock); check_accounts (); gl_recursive_lock_unlock (my_reclock); - dbgprintf ("Checker %p after check unlock\n", gl_thread_self ()); + dbgprintf ("Checker %p after check unlock\n", gl_thread_self_pointer ()); yield (); } - dbgprintf ("Checker %p dying.\n", gl_thread_self ()); + dbgprintf ("Checker %p dying.\n", gl_thread_self_pointer ()); return NULL; } @@ -444,7 +444,7 @@ once_contender_thread (void *arg) break; dbgprintf ("Contender %p waiting for signal for round %d\n", - gl_thread_self (), repeat); + gl_thread_self_pointer (), repeat); #if ENABLE_LOCKING /* Wait for the signal to go. */ gl_rwlock_rdlock (fire_signal[repeat]); @@ -456,7 +456,7 @@ once_contender_thread (void *arg) yield (); #endif dbgprintf ("Contender %p got the signal for round %d\n", - gl_thread_self (), repeat); + gl_thread_self_pointer (), repeat); /* Contend for execution. */ gl_once (once_control, once_execute); diff --git a/tests/test-tls.c b/tests/test-tls.c index e8d66b667..153038d05 100644 --- a/tests/test-tls.c +++ b/tests/test-tls.c @@ -89,7 +89,7 @@ worker_thread (void *arg) int i, j, repeat; unsigned int values[KEYS_COUNT]; - dbgprintf ("Worker %p started\n", gl_thread_self ()); + dbgprintf ("Worker %p started\n", gl_thread_self_pointer ()); /* Initialize the per-thread storage. */ for (i = 0; i < KEYS_COUNT; i++) @@ -102,28 +102,28 @@ worker_thread (void *arg) perhaps_yield (); /* Verify that the initial value is NULL. */ - dbgprintf ("Worker %p before initial verify\n", gl_thread_self ()); + dbgprintf ("Worker %p before initial verify\n", gl_thread_self_pointer ()); for (i = 0; i < KEYS_COUNT; i++) if (gl_tls_get (mykeys[i]) != NULL) abort (); - dbgprintf ("Worker %p after initial verify\n", gl_thread_self ()); + dbgprintf ("Worker %p after initial verify\n", gl_thread_self_pointer ()); perhaps_yield (); /* Initialize the per-thread storage. */ - dbgprintf ("Worker %p before first tls_set\n", gl_thread_self ()); + dbgprintf ("Worker %p before first tls_set\n", gl_thread_self_pointer ()); for (i = 0; i < KEYS_COUNT; i++) { unsigned int *ptr = (unsigned int *) malloc (sizeof (unsigned int)); *ptr = values[i]; gl_tls_set (mykeys[i], ptr); } - dbgprintf ("Worker %p after first tls_set\n", gl_thread_self ()); + dbgprintf ("Worker %p after first tls_set\n", gl_thread_self_pointer ()); perhaps_yield (); /* Shuffle around the pointers. */ for (repeat = REPEAT_COUNT; repeat > 0; repeat--) { - dbgprintf ("Worker %p doing value swapping\n", gl_thread_self ()); + dbgprintf ("Worker %p doing value swapping\n", gl_thread_self_pointer ()); i = ((unsigned int) rand () >> 3) % KEYS_COUNT; j = ((unsigned int) rand () >> 3) % KEYS_COUNT; if (i != j) @@ -138,14 +138,14 @@ worker_thread (void *arg) } /* Verify that all the values are from this thread. */ - dbgprintf ("Worker %p before final verify\n", gl_thread_self ()); + dbgprintf ("Worker %p before final verify\n", gl_thread_self_pointer ()); for (i = 0; i < KEYS_COUNT; i++) if ((*(unsigned int *) gl_tls_get (mykeys[i]) % THREAD_COUNT) != id) abort (); - dbgprintf ("Worker %p after final verify\n", gl_thread_self ()); + dbgprintf ("Worker %p after final verify\n", gl_thread_self_pointer ()); perhaps_yield (); - dbgprintf ("Worker %p dying.\n", gl_thread_self ()); + dbgprintf ("Worker %p dying.\n", gl_thread_self_pointer ()); return NULL; }