diff options
author | Sergey Bugaev <bugaevc@gmail.com> | 2021-09-15 20:11:09 +0300 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2021-09-16 01:04:17 +0200 |
commit | ed2f9aaf5e901e8561cca8d0370ff3bcb2b6482b (patch) | |
tree | 93a1647a14e192d0e8bc698d8d3e3d4f9c08d6d7 /sysdeps/htl | |
parent | 166bb3eac351b88191d440b0fe8d5d7b757eaed0 (diff) | |
download | glibc-ed2f9aaf5e901e8561cca8d0370ff3bcb2b6482b.zip glibc-ed2f9aaf5e901e8561cca8d0370ff3bcb2b6482b.tar.gz glibc-ed2f9aaf5e901e8561cca8d0370ff3bcb2b6482b.tar.bz2 |
htl: Reimplement GSCOPE
This is a new implementation of GSCOPE which largely mirrors its NPTL
counterpart. Same as in NPTL, instead of a global flag shared between
threads, there is now a per-thread GSCOPE flag stored in each thread's
TCB. This makes entering and exiting a GSCOPE faster at the expense of
making THREAD_GSCOPE_WAIT () slower.
The largest win is the elimination of many redundant gsync_wake () RPC
calls; previously, even simplest programs would make dozens of fully
redundant gsync_wake () calls.
Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
Message-Id: <20210915171110.226187-3-bugaevc@gmail.com>
Reviewed-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Diffstat (limited to 'sysdeps/htl')
-rw-r--r-- | sysdeps/htl/dl-thread_gscope_wait.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/sysdeps/htl/dl-thread_gscope_wait.c b/sysdeps/htl/dl-thread_gscope_wait.c new file mode 100644 index 0000000..7557e77 --- /dev/null +++ b/sysdeps/htl/dl-thread_gscope_wait.c @@ -0,0 +1,55 @@ +/* Out-of-line notification function for the GSCOPE locking mechanism. + Copyright (C) 2007-2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <ldsodefs.h> +#include <pthread.h> +#include <htl/pt-internal.h> + +void +__thread_gscope_wait (void) +{ + size_t i; + struct __pthread *t; + int *gscope_flagp; + + __libc_rwlock_rdlock (GL (dl_pthread_threads_lock)); + + /* Iterate over the list of threads. */ + for (i = 0; i < GL (dl_pthread_num_threads); ++i) + { + t = GL (dl_pthread_threads[i]); + if (t == NULL || t->tcb->gscope_flag == THREAD_GSCOPE_FLAG_UNUSED) + continue; + + gscope_flagp = &t->tcb->gscope_flag; + + /* We have to wait until this thread is done with the global + scope. First tell the thread that we are waiting and + possibly have to be woken. */ + if (atomic_compare_and_exchange_bool_acq (gscope_flagp, + THREAD_GSCOPE_FLAG_WAIT, + THREAD_GSCOPE_FLAG_USED)) + continue; + + do + lll_wait (gscope_flagp, THREAD_GSCOPE_FLAG_WAIT, LLL_PRIVATE); + while (*gscope_flagp == THREAD_GSCOPE_FLAG_WAIT); + } + + __libc_rwlock_unlock (GL (dl_pthread_threads_lock)); +} |