diff options
author | Ulrich Drepper <drepper@redhat.com> | 2006-09-08 10:41:17 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2006-09-08 10:41:17 +0000 |
commit | 346e6ad4016f3a19f71ccd0edd8a2682746d6fe7 (patch) | |
tree | f96d1336d032a8b0d2438378e4fe621b7a5590f9 /nptl/tst-cond22.c | |
parent | 469615bdd422cec2d89a09c765a8e965faa29722 (diff) | |
download | glibc-346e6ad4016f3a19f71ccd0edd8a2682746d6fe7.zip glibc-346e6ad4016f3a19f71ccd0edd8a2682746d6fe7.tar.gz glibc-346e6ad4016f3a19f71ccd0edd8a2682746d6fe7.tar.bz2 |
[BZ #3123]
2006-09-08 Ulrich Drepper <drepper@redhat.com>
[BZ #3123]
* sysdeps/pthread/pthread_cond_wait.c (__condvar_cleanup): Don't
increment WAKEUP_SEQ if this would increase the value beyond TOTAL_SEQ.
* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.c: Likewise.
* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.c: Likewise.
* sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.c: Likewise.
* Makefile (tests): Add tst-cond22.
* tst-cond22.c: New file.
Diffstat (limited to 'nptl/tst-cond22.c')
-rw-r--r-- | nptl/tst-cond22.c | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/nptl/tst-cond22.c b/nptl/tst-cond22.c new file mode 100644 index 0000000..0e829ff --- /dev/null +++ b/nptl/tst-cond22.c @@ -0,0 +1,153 @@ +#include <pthreadP.h> +#include <stdio.h> + + +static pthread_barrier_t b; +static pthread_cond_t c = PTHREAD_COND_INITIALIZER; +static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; + + +static void +cl (void *arg) +{ + pthread_mutex_unlock (&m); +} + + +static void * +tf (void *arg) +{ + if (pthread_mutex_lock (&m) != 0) + { + printf ("%s: mutex_lock failed\n", __func__); + exit (1); + } + int e = pthread_barrier_wait (&b); + if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) + { + printf ("%s: barrier_wait failed\n", __func__); + exit (1); + } + pthread_cleanup_push (cl, NULL); + if (pthread_cond_wait (&c, &m) != 0) + { + printf ("%s: cond_wait failed\n", __func__); + exit (1); + } + pthread_cleanup_pop (0); + if (pthread_mutex_unlock (&m) != 0) + { + printf ("%s: mutex_unlock failed\n", __func__); + exit (1); + } + return NULL; +} + + +static int +do_test (void) +{ + int status = 0; + + if (pthread_barrier_init (&b, NULL, 2) != 0) + { + puts ("barrier_init failed"); + return 1; + } + + pthread_t th; + if (pthread_create (&th, NULL, tf, NULL) != 0) + { + puts ("1st create failed"); + return 1; + } + int e = pthread_barrier_wait (&b); + if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("1st barrier_wait failed"); + return 1; + } + if (pthread_mutex_lock (&m) != 0) + { + puts ("1st mutex_lock failed"); + return 1; + } + if (pthread_cond_signal (&c) != 0) + { + puts ("1st cond_signal failed"); + return 1; + } + if (pthread_cancel (th) != 0) + { + puts ("cancel failed"); + return 1; + } + if (pthread_mutex_unlock (&m) != 0) + { + puts ("1st mutex_unlock failed"); + return 1; + } + void *res; + if (pthread_join (th, &res) != 0) + { + puts ("1st join failed"); + return 1; + } + if (res != PTHREAD_CANCELED) + { + puts ("first thread not canceled"); + status = 1; + } + + printf ("cond = { %d, %x, %lld, %lld, %lld, %p, %u, %u }\n", + c.__data.__lock, c.__data.__futex, c.__data.__total_seq, + c.__data.__wakeup_seq, c.__data.__woken_seq, c.__data.__mutex, + c.__data.__nwaiters, c.__data.__broadcast_seq); + + if (pthread_create (&th, NULL, tf, NULL) != 0) + { + puts ("2nd create failed"); + return 1; + } + e = pthread_barrier_wait (&b); + if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) + { + puts ("2nd barrier_wait failed"); + return 1; + } + if (pthread_mutex_lock (&m) != 0) + { + puts ("2nd mutex_lock failed"); + return 1; + } + if (pthread_cond_signal (&c) != 0) + { + puts ("2nd cond_signal failed"); + return 1; + } + if (pthread_mutex_unlock (&m) != 0) + { + puts ("2nd mutex_unlock failed"); + return 1; + } + if (pthread_join (th, &res) != 0) + { + puts ("2nd join failed"); + return 1; + } + if (res != NULL) + { + puts ("2nd thread canceled"); + status = 1; + } + + printf ("cond = { %d, %x, %lld, %lld, %lld, %p, %u, %u }\n", + c.__data.__lock, c.__data.__futex, c.__data.__total_seq, + c.__data.__wakeup_seq, c.__data.__woken_seq, c.__data.__mutex, + c.__data.__nwaiters, c.__data.__broadcast_seq); + + return status; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" |