]>
Commit | Line | Data |
---|---|---|
2b778ceb | 1 | /* Copyright (C) 2002-2021 Free Software Foundation, Inc. |
76a50749 | 2 | This file is part of the GNU C Library. |
76a50749 UD |
3 | |
4 | The GNU C Library is free software; you can redistribute it and/or | |
5 | modify it under the terms of the GNU Lesser General Public | |
6 | License as published by the Free Software Foundation; either | |
7 | version 2.1 of the License, or (at your option) any later version. | |
8 | ||
9 | The GNU C Library is distributed in the hope that it will be useful, | |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
12 | Lesser General Public License for more details. | |
13 | ||
14 | You should have received a copy of the GNU Lesser General Public | |
59ba27a6 | 15 | License along with the GNU C Library; if not, see |
5a82c748 | 16 | <https://www.gnu.org/licenses/>. */ |
76a50749 | 17 | |
73f7c32c | 18 | #include <errno.h> |
bf293afe | 19 | #include <shlib-compat.h> |
76a50749 | 20 | #include "pthreadP.h" |
5acf7263 | 21 | #include <stap-probe.h> |
ed19993b TR |
22 | #include <atomic.h> |
23 | #include <futex-internal.h> | |
24 | ||
25 | #include "pthread_cond_common.c" | |
26 | ||
27 | /* See __pthread_cond_wait for a high-level description of the algorithm. | |
28 | ||
29 | A correct program must make sure that no waiters are blocked on the condvar | |
30 | when it is destroyed, and that there are no concurrent signals or | |
31 | broadcasts. To wake waiters reliably, the program must signal or | |
32 | broadcast while holding the mutex or after having held the mutex. It must | |
33 | also ensure that no signal or broadcast are still pending to unblock | |
34 | waiters; IOW, because waiters can wake up spuriously, the program must | |
35 | effectively ensure that destruction happens after the execution of those | |
36 | signal or broadcast calls. | |
37 | Thus, we can assume that all waiters that are still accessing the condvar | |
38 | have been woken. We wait until they have confirmed to have woken up by | |
39 | decrementing __wrefs. */ | |
76a50749 | 40 | int |
9d46370c | 41 | __pthread_cond_destroy (pthread_cond_t *cond) |
76a50749 | 42 | { |
5acf7263 RM |
43 | LIBC_PROBE (cond_destroy, 1, cond); |
44 | ||
ed19993b TR |
45 | /* Set the wake request flag. We could also spin, but destruction that is |
46 | concurrent with still-active waiters is probably neither common nor | |
47 | performance critical. Acquire MO to synchronize with waiters confirming | |
48 | that they finished. */ | |
49 | unsigned int wrefs = atomic_fetch_or_acquire (&cond->__data.__wrefs, 4); | |
50 | int private = __condvar_get_private (wrefs); | |
51 | while (wrefs >> 3 != 0) | |
73f7c32c | 52 | { |
ed19993b TR |
53 | futex_wait_simple (&cond->__data.__wrefs, wrefs, private); |
54 | /* See above. */ | |
55 | wrefs = atomic_load_acquire (&cond->__data.__wrefs); | |
73f7c32c | 56 | } |
ed19993b | 57 | /* The memory the condvar occupies can now be reused. */ |
76a50749 UD |
58 | return 0; |
59 | } | |
dc6cfdc9 FW |
60 | libc_hidden_def (__pthread_cond_destroy) |
61 | versioned_symbol (libc, __pthread_cond_destroy, | |
bf293afe | 62 | pthread_cond_destroy, GLIBC_2_3_2); |