git: 982584532dc3 - stable/13 - rtld: mask signals for default read locks
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 18 Sep 2022 00:34:42 UTC
The branch stable/13 has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=982584532dc3c8fba292b370c8444f6a2b3f3010
commit 982584532dc3c8fba292b370c8444f6a2b3f3010
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2022-08-30 12:46:30 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2022-09-18 00:33:45 +0000
rtld: mask signals for default read locks
(cherry picked from commit a687683b997c5805ecd6d8278798b7ef00d9908f)
---
libexec/rtld-elf/rtld_lock.c | 60 ++++++++++++++++++++++++++------------------
1 file changed, 36 insertions(+), 24 deletions(-)
diff --git a/libexec/rtld-elf/rtld_lock.c b/libexec/rtld-elf/rtld_lock.c
index e501c03f0722..8b9a6a51e061 100644
--- a/libexec/rtld-elf/rtld_lock.c
+++ b/libexec/rtld-elf/rtld_lock.c
@@ -124,16 +124,6 @@ def_lock_destroy(void *lock)
free(l->base);
}
-static void
-def_rlock_acquire(void *lock)
-{
- Lock *l = (Lock *)lock;
-
- atomic_add_acq_int(&l->lock, RC_INCR);
- while (l->lock & WAFLAG)
- ; /* Spin */
-}
-
static void
sig_fastunblock(void)
{
@@ -145,24 +135,37 @@ sig_fastunblock(void)
__sys_sigfastblock(SIGFASTBLOCK_UNBLOCK, NULL);
}
+static bool
+def_lock_acquire_set(Lock *l, bool wlock)
+{
+ if (wlock) {
+ if (atomic_cmpset_acq_int(&l->lock, 0, WAFLAG))
+ return (true);
+ } else {
+ atomic_add_acq_int(&l->lock, RC_INCR);
+ if ((l->lock & WAFLAG) == 0)
+ return (true);
+ atomic_add_int(&l->lock, -RC_INCR);
+ }
+ return (false);
+}
+
static void
-def_wlock_acquire(void *lock)
+def_lock_acquire(Lock *l, bool wlock)
{
- Lock *l;
sigset_t tmp_oldsigmask;
- l = (Lock *)lock;
if (ld_fast_sigblock) {
for (;;) {
atomic_add_32(&fsigblock, SIGFASTBLOCK_INC);
- if (atomic_cmpset_acq_int(&l->lock, 0, WAFLAG))
+ if (def_lock_acquire_set(l, wlock))
break;
sig_fastunblock();
}
} else {
for (;;) {
sigprocmask(SIG_BLOCK, &fullsigmask, &tmp_oldsigmask);
- if (atomic_cmpset_acq_int(&l->lock, 0, WAFLAG))
+ if (def_lock_acquire_set(l, wlock))
break;
sigprocmask(SIG_SETMASK, &tmp_oldsigmask, NULL);
}
@@ -171,21 +174,30 @@ def_wlock_acquire(void *lock)
}
}
+static void
+def_rlock_acquire(void *lock)
+{
+ def_lock_acquire(lock, false);
+}
+
+static void
+def_wlock_acquire(void *lock)
+{
+ def_lock_acquire(lock, true);
+}
+
static void
def_lock_release(void *lock)
{
Lock *l;
l = (Lock *)lock;
- if ((l->lock & WAFLAG) == 0)
- atomic_add_rel_int(&l->lock, -RC_INCR);
- else {
- atomic_add_rel_int(&l->lock, -WAFLAG);
- if (ld_fast_sigblock)
- sig_fastunblock();
- else if (atomic_fetchadd_int(&wnested, -1) == 1)
- sigprocmask(SIG_SETMASK, &oldsigmask, NULL);
- }
+ atomic_add_rel_int(&l->lock, -((l->lock & WAFLAG) == 0 ?
+ RC_INCR : WAFLAG));
+ if (ld_fast_sigblock)
+ sig_fastunblock();
+ else if (atomic_fetchadd_int(&wnested, -1) == 1)
+ sigprocmask(SIG_SETMASK, &oldsigmask, NULL);
}
static int