1 /* Out-of-line notification function for the GSCOPE locking mechanism.
2    Copyright (C) 2007-2021 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 #include <ldsodefs.h>
20 #include <pthread.h>
21 #include <htl/pt-internal.h>
22 
23 void
__thread_gscope_wait(void)24 __thread_gscope_wait (void)
25 {
26   size_t i;
27   struct __pthread *t;
28   int *gscope_flagp;
29 
30   __libc_rwlock_rdlock (GL (dl_pthread_threads_lock));
31 
32   /* Iterate over the list of threads.  */
33   for (i = 0; i < GL (dl_pthread_num_threads); ++i)
34     {
35       t = GL (dl_pthread_threads[i]);
36       if (t == NULL || t->tcb->gscope_flag == THREAD_GSCOPE_FLAG_UNUSED)
37         continue;
38 
39       gscope_flagp = &t->tcb->gscope_flag;
40 
41       /* We have to wait until this thread is done with the global
42          scope.  First tell the thread that we are waiting and
43          possibly have to be woken.  */
44       if (atomic_compare_and_exchange_bool_acq (gscope_flagp,
45                                                 THREAD_GSCOPE_FLAG_WAIT,
46                                                 THREAD_GSCOPE_FLAG_USED))
47         continue;
48 
49       do
50         lll_wait (gscope_flagp, THREAD_GSCOPE_FLAG_WAIT, LLL_PRIVATE);
51       while (*gscope_flagp == THREAD_GSCOPE_FLAG_WAIT);
52     }
53 
54   __libc_rwlock_unlock (GL (dl_pthread_threads_lock));
55 }
56