aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/htl/pt-cond-destroy.c
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2020-06-01 17:27:48 +0000
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2020-06-01 17:38:31 +0000
commit8081702460726304af496be52234385094392a6f (patch)
tree55606e2a42e6342aaed360c27c17e9675c9c478e /sysdeps/htl/pt-cond-destroy.c
parenta3e589d1f68d43d4c3f67d59497862875c2d5afc (diff)
downloadglibc-8081702460726304af496be52234385094392a6f.zip
glibc-8081702460726304af496be52234385094392a6f.tar.gz
glibc-8081702460726304af496be52234385094392a6f.tar.bz2
htl: Make pthread_cond_destroy wait for threads to be woken
This allows to reuse the storage after calling pthread_cond_destroy. * sysdeps/htl/bits/types/struct___pthread_cond.h (__pthread_cond): Replace unused struct __pthread_condimpl *__impl field with unsigned int __wrefs. (__PTHREAD_COND_INITIALIZER): Update accordingly. * sysdeps/htl/pt-cond-timedwait.c (__pthread_cond_timedwait_internal): Register as waiter in __wrefs field. On unregistering, wake any pending pthread_cond_destroy. * sysdeps/htl/pt-cond-destroy.c (__pthread_cond_destroy): Register wake request in __wrefs. * nptl/Makefile (tests): Move tst-cond20 tst-cond21 to... * sysdeps/pthread/Makefile (tests): ... here. * nptl/tst-cond20.c nptl/tst-cond21.c: Move to... * sysdeps/pthread/tst-cond20.c sysdeps/pthread/tst-cond21.c: ... here.
Diffstat (limited to 'sysdeps/htl/pt-cond-destroy.c')
-rw-r--r--sysdeps/htl/pt-cond-destroy.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/sysdeps/htl/pt-cond-destroy.c b/sysdeps/htl/pt-cond-destroy.c
index 0664f3f..722516a 100644
--- a/sysdeps/htl/pt-cond-destroy.c
+++ b/sysdeps/htl/pt-cond-destroy.c
@@ -22,14 +22,26 @@
int
__pthread_cond_destroy (pthread_cond_t *cond)
{
- int ret = 0;
+ /* Set the wake request flag. */
+ unsigned int wrefs = atomic_fetch_or_acquire (&cond->__wrefs, 1);
__pthread_spin_wait (&cond->__lock);
if (cond->__queue)
- ret = EBUSY;
+ {
+ __pthread_spin_unlock (&cond->__lock);
+ return EBUSY;
+ }
__pthread_spin_unlock (&cond->__lock);
- return ret;
+ while (wrefs >> 1 != 0)
+ {
+ gsync_wait (__mach_task_self (), (vm_offset_t) &cond->__wrefs, wrefs,
+ 0, 0, 0);
+ wrefs = atomic_load_acquire (&cond->__wrefs);
+ }
+ /* The memory the condvar occupies can now be reused. */
+
+ return 0;
}
weak_alias (__pthread_cond_destroy, pthread_cond_destroy);