diff options
author | Ulrich Drepper <drepper@redhat.com> | 2004-09-02 18:59:24 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2004-09-02 18:59:24 +0000 |
commit | 73f7c32c47ab2397935d9fc2aeaa594794b38c7e (patch) | |
tree | 1a0f7d20c9009fbd67c33495f9db0a5d665092b3 /nptl/sysdeps/pthread/pthread_cond_wait.c | |
parent | 86aca5ac58e152336e676bc1231acac6adc32068 (diff) | |
download | glibc-73f7c32c47ab2397935d9fc2aeaa594794b38c7e.tar.gz glibc-73f7c32c47ab2397935d9fc2aeaa594794b38c7e.tar.xz glibc-73f7c32c47ab2397935d9fc2aeaa594794b38c7e.zip |
[BZ #357]
Update. 2004-09-02 Steven Munroe <sjmunroe@us.ibm.com> [BZ #357] * stdlib/tst-setcontext.c (test_stack): Added test for stack clobber. (main): Call test_stack. * sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S (__getcontext): Push stack frame then save parms in local frame. Improve instruction scheduling. * sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S (__swapcontext): Likewise.
Diffstat (limited to 'nptl/sysdeps/pthread/pthread_cond_wait.c')
-rw-r--r-- | nptl/sysdeps/pthread/pthread_cond_wait.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/nptl/sysdeps/pthread/pthread_cond_wait.c b/nptl/sysdeps/pthread/pthread_cond_wait.c index 45187b5240..86669458a0 100644 --- a/nptl/sysdeps/pthread/pthread_cond_wait.c +++ b/nptl/sysdeps/pthread/pthread_cond_wait.c @@ -42,6 +42,7 @@ __condvar_cleanup (void *arg) { struct _condvar_cleanup_buffer *cbuffer = (struct _condvar_cleanup_buffer *) arg; + unsigned int destroying; /* We are going to modify shared data. */ lll_mutex_lock (cbuffer->cond->__data.__lock); @@ -55,11 +56,25 @@ __condvar_cleanup (void *arg) ++cbuffer->cond->__data.__futex; } + cbuffer->cond->__data.__nwaiters -= 1 << COND_CLOCK_BITS; + + /* If pthread_cond_destroy was called on this variable already, + notify the pthread_cond_destroy caller all waiters have left + and it can be successfully destroyed. */ + destroying = 0; + if (cbuffer->cond->__data.__total_seq == -1ULL + && cbuffer->cond->__data.__nwaiters < (1 << COND_CLOCK_BITS)) + { + lll_futex_wake (&cbuffer->cond->__data.__nwaiters, 1); + destroying = 1; + } + /* We are done. */ lll_mutex_unlock (cbuffer->cond->__data.__lock); /* Wake everybody to make sure no condvar signal gets lost. */ - lll_futex_wake (&cbuffer->cond->__data.__futex, INT_MAX); + if (! destroying) + lll_futex_wake (&cbuffer->cond->__data.__futex, INT_MAX); /* Get the mutex before returning unless asynchronous cancellation is in effect. */ @@ -90,6 +105,7 @@ __pthread_cond_wait (cond, mutex) /* We have one new user of the condvar. */ ++cond->__data.__total_seq; ++cond->__data.__futex; + cond->__data.__nwaiters += 1 << COND_CLOCK_BITS; /* Remember the mutex we are using here. If there is already a different address store this is a bad user bug. Do not store @@ -145,6 +161,16 @@ __pthread_cond_wait (cond, mutex) ++cond->__data.__woken_seq; bc_out: + + cond->__data.__nwaiters -= 1 << COND_CLOCK_BITS; + + /* If pthread_cond_destroy was called on this varaible already, + notify the pthread_cond_destroy caller all waiters have left + and it can be successfully destroyed. */ + if (cond->__data.__total_seq == -1ULL + && cond->__data.__nwaiters < (1 << COND_CLOCK_BITS)) + lll_futex_wake (&cond->__data.__nwaiters, 1); + /* We are done with the condvar. */ lll_mutex_unlock (cond->__data.__lock); |