diff options
author | Daiki Ueno <ueno@unixuser.org> | 2012-12-17 09:10:09 +0900 |
---|---|---|
committer | Daiki Ueno <ueno@unixuser.org> | 2012-12-19 07:52:26 +0900 |
commit | 443d2b40a9a1bcdae1f10fbe3094a8cfdbc82269 (patch) | |
tree | b2f5ea737f6f4b4d310b890f1209324624f4bed4 /gettext-runtime/tests/test-lock.c | |
parent | 0cde5e7f08515dd4f3dcd71c4546519a306a2027 (diff) | |
download | gettext-443d2b40a9a1bcdae1f10fbe3094a8cfdbc82269.tar.gz |
test-lock: work around pthread-win32 and merge gnulib changes
test-lock: work around pthread-win32
* test-lock.c (gl_thread_self_pointer): Renamed from
gl_thread_self; all callers changed. Work around pthread-win32.
(gl_thread_join): Add extra RETVALP argument; all callers changed.
test-lock: merge gnulib changes
2011-06-09 Bruno Haible <bruno@clisp.org>
* test-lock.c: Use gl_thread_self_pointer instead of
gl_thread_self.
2010-03-25 Bruno Haible <bruno@clisp.org>
Minor formatting changes.
* test-lock.c: Insert space before function argument list.
Reported by Jim Meyering.
2008-12-07 Bruno Haible <bruno@clisp.org>
* test-lock.c (test_lock, test_rwlock, test_recursive_lock)
(test_once): Mark functions as static.
2008-09-30 Yoann Vandoorselaere <yoann.v@prelude-ids.com>
Bruno Haible <bruno@clisp.org>
* test-lock.c (test_lock, test_rwlock, test_recursive_lock)
(test_once): Pass an additional NULL argument to gl_thread_join.
2008-09-21 Bruno Haible <bruno@clisp.org>
* test-lock.c (main): Tweak skip message.
2008-08-22 Eric Blake <ebb9@byu.net>
test-lock: mention why a test is skipped
* test-lock.c (main) [!USE_*_THREADS]: Print why test is skipped.
2007-05-28 Eric Blake <ebb9@byu.net>
Unconditionally include <config.h> in unit tests.
test-lock.c: Remove #ifdef HAVE_CONFIG_H.
Diffstat (limited to 'gettext-runtime/tests/test-lock.c')
-rw-r--r-- | gettext-runtime/tests/test-lock.c | 145 |
1 files changed, 82 insertions, 63 deletions
diff --git a/gettext-runtime/tests/test-lock.c b/gettext-runtime/tests/test-lock.c index a3047b9f2..d27cac4fc 100644 --- a/gettext-runtime/tests/test-lock.c +++ b/gettext-runtime/tests/test-lock.c @@ -1,5 +1,5 @@ /* Test of locking in multithreaded situations. - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2008-2012 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -16,9 +16,7 @@ /* Written by Bruno Haible <bruno@clisp.org>, 2005. */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif +#include <config.h> #if USE_POSIX_THREADS || USE_SOLARIS_THREADS || USE_PTH_THREADS || USE_WINDOWS_THREADS @@ -92,19 +90,22 @@ static inline gl_thread_t gl_thread_create (void * (*func) (void *), void *arg) abort (); return thread; } -static inline void gl_thread_join (gl_thread_t thread) +static inline void gl_thread_join (gl_thread_t thread, void **retvalp) { - void *retval; - if (pthread_join (thread, &retval) != 0) + if (pthread_join (thread, retvalp) != 0) abort (); } static inline void gl_thread_yield (void) { sched_yield (); } -static inline void * gl_thread_self (void) +static inline void * gl_thread_self_pointer (void) { +# ifdef PTW32_VERSION + return pthread_self ().p; +# else return (void *) pthread_self (); +# endif } #endif #if TEST_PTH_THREADS @@ -117,16 +118,16 @@ static inline gl_thread_t gl_thread_create (void * (*func) (void *), void *arg) abort (); return thread; } -static inline void gl_thread_join (gl_thread_t thread) +static inline void gl_thread_join (gl_thread_t thread, void **retvalp) { - if (!pth_join (thread, NULL)) + if (!pth_join (thread, retvalp)) abort (); } static inline void gl_thread_yield (void) { pth_yield (NULL); } -static inline void * gl_thread_self (void) +static inline void * gl_thread_self_pointer (void) { return pth_self (); } @@ -141,17 +142,16 @@ static inline gl_thread_t gl_thread_create (void * (*func) (void *), void *arg) abort (); return thread; } -static inline void gl_thread_join (gl_thread_t thread) +static inline void gl_thread_join (gl_thread_t thread, void **retvalp) { - void *retval; - if (thr_join (thread, NULL, &retval) != 0) + if (thr_join (thread, NULL, retvalp) != 0) abort (); } static inline void gl_thread_yield (void) { thr_yield (); } -static inline void * gl_thread_self (void) +static inline void * gl_thread_self_pointer (void) { return (void *) thr_self (); } @@ -187,8 +187,9 @@ static inline gl_thread_t gl_thread_create (void * (*func) (void *), void *arg) return thread; } } -static inline void gl_thread_join (gl_thread_t thread) +static inline void gl_thread_join (gl_thread_t thread, void **retvalp) { + (void) retvalp; if (WaitForSingleObject (thread, INFINITE) == WAIT_FAILED) abort (); if (!CloseHandle (thread)) @@ -198,7 +199,7 @@ static inline void gl_thread_yield (void) { Sleep (0); } -static inline void * gl_thread_self (void) +static inline void * gl_thread_self_pointer (void) { return (void *) GetCurrentThreadId (); } @@ -216,7 +217,7 @@ static int account[ACCOUNT_COUNT]; static int random_account (void) { - return ((unsigned int) rand() >> 3) % ACCOUNT_COUNT; + return ((unsigned int) rand () >> 3) % ACCOUNT_COUNT; } static void @@ -231,6 +232,9 @@ check_accounts (void) abort (); } + +/* ------------------- Test normal (non-recursive) locks ------------------- */ + /* Test normal locks by having several bank accounts and several threads which shuffle around money between the accounts and another thread checking that all the money is still there. */ @@ -246,30 +250,30 @@ 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 (); - value = ((unsigned int) rand() >> 3) % 10; + value = ((unsigned int) rand () >> 3) % 10; 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; } @@ -280,20 +284,20 @@ 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; } -void +static void test_lock (void) { int i; @@ -312,12 +316,15 @@ test_lock (void) /* Wait for the threads to terminate. */ for (i = 0; i < THREAD_COUNT; i++) - gl_thread_join (threads[i]); + gl_thread_join (threads[i], NULL); lock_checker_done = 1; - gl_thread_join (checkerthread); + gl_thread_join (checkerthread, NULL); check_accounts (); } + +/* ----------------- Test read-write (non-recursive) locks ----------------- */ + /* Test read-write locks by having several bank accounts and several threads which shuffle around money between the accounts and several other threads that check that all the money is still there. */ @@ -333,24 +340,24 @@ 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 (); - value = ((unsigned int) rand() >> 3) % 10; + value = ((unsigned int) rand () >> 3) % 10; 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; } @@ -361,20 +368,20 @@ 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; } -void +static void test_rwlock (void) { int i; @@ -394,13 +401,16 @@ test_rwlock (void) /* Wait for the threads to terminate. */ for (i = 0; i < THREAD_COUNT; i++) - gl_thread_join (threads[i]); + gl_thread_join (threads[i], NULL); rwlock_checker_done = 1; for (i = 0; i < THREAD_COUNT; i++) - gl_thread_join (checkerthreads[i]); + gl_thread_join (checkerthreads[i], NULL); check_accounts (); } + +/* -------------------------- Test recursive locks -------------------------- */ + /* Test recursive locks by having several bank accounts and several threads which shuffle around money between the accounts (recursively) and another thread checking that all the money is still there. */ @@ -412,23 +422,23 @@ 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 (); - value = ((unsigned int) rand() >> 3) % 10; + value = ((unsigned int) rand () >> 3) % 10; account[i1] += value; account[i2] -= value; /* Recursive with probability 0.5. */ - if (((unsigned int) rand() >> 3) % 2) + 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 * @@ -440,16 +450,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; } @@ -460,20 +470,20 @@ 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; } -void +static void test_recursive_lock (void) { int i; @@ -492,12 +502,15 @@ test_recursive_lock (void) /* Wait for the threads to terminate. */ for (i = 0; i < THREAD_COUNT; i++) - gl_thread_join (threads[i]); + gl_thread_join (threads[i], NULL); reclock_checker_done = 1; - gl_thread_join (checkerthread); + gl_thread_join (checkerthread, NULL); check_accounts (); } + +/* ------------------------ Test once-only execution ------------------------ */ + /* Test once-only execution by having several threads attempt to grab a once-only task simultaneously (triggered by releasing a read-write lock). */ @@ -538,7 +551,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]); @@ -550,7 +563,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); @@ -559,7 +572,7 @@ once_contender_thread (void *arg) return NULL; } -void +static void test_once (void) { int i, repeat; @@ -641,9 +654,12 @@ test_once (void) /* Wait for the threads to terminate. */ for (i = 0; i < THREAD_COUNT; i++) - gl_thread_join (threads[i]); + gl_thread_join (threads[i], NULL); } + +/* -------------------------------------------------------------------------- */ + int main () { @@ -680,9 +696,12 @@ main () /* No multithreading available. */ +#include <stdio.h> + int main () { + fputs ("Skipping test: multithreading not enabled\n", stderr); return 77; } |