mirror of
https://git.savannah.gnu.org/git/gnulib.git
synced 2025-08-17 12:41:05 +03:00
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.
This commit is contained in:
13
ChangeLog
13
ChangeLog
@@ -1,3 +1,16 @@
|
||||
2011-06-09 Bruno Haible <bruno@clisp.org>
|
||||
|
||||
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 <bruno@clisp.org>
|
||||
|
||||
thread: Fix confusion between NULL and 0.
|
||||
|
@@ -29,6 +29,20 @@
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
#if USE_POSIX_THREADS
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef PTW32_VERSION
|
||||
|
||||
const gl_thread_t gl_null_thread /* = { .p = NULL } */;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
#if USE_WIN32_THREADS
|
||||
|
||||
#include <process.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
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user