thr_rtld: accept read lock requests while owning the lock for write

PR:	286505
Reviewed by:	olce
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D50117
This commit is contained in:
Konstantin Belousov
2025-05-02 18:09:46 +03:00
parent c66c0a8479
commit 812c4bf3f1
+21 -5
View File
@@ -50,8 +50,11 @@ static int _thr_rtld_set_flag(int);
static void _thr_rtld_wlock_acquire(void *);
struct rtld_lock {
struct urwlock lock;
char _pad[CACHE_LINE_SIZE - sizeof(struct urwlock)];
struct urwlock lock;
struct pthread *wowner;
u_int rlocks;
char _pad[CACHE_LINE_SIZE - sizeof(struct urwlock) -
sizeof(struct pthread *) - sizeof(u_int)];
};
static struct rtld_lock lock_place[MAX_RTLD_LOCKS] __aligned(CACHE_LINE_SIZE);
@@ -116,9 +119,13 @@ _thr_rtld_rlock_acquire(void *lock)
SAVE_ERRNO();
l = (struct rtld_lock *)lock;
THR_CRITICAL_ENTER(curthread);
while (_thr_rwlock_rdlock(&l->lock, 0, NULL) != 0)
;
if (l->wowner == curthread) {
l->rlocks++;
} else {
THR_CRITICAL_ENTER(curthread);
while (_thr_rwlock_rdlock(&l->lock, 0, NULL) != 0)
;
}
curthread->rdlock_count++;
RESTORE_ERRNO();
}
@@ -137,6 +144,7 @@ _thr_rtld_wlock_acquire(void *lock)
THR_CRITICAL_ENTER(curthread);
while (_thr_rwlock_wrlock(&l->lock, NULL) != 0)
;
l->wowner = curthread;
RESTORE_ERRNO();
}
@@ -164,6 +172,14 @@ _thr_rtld_lock_release(void *lock)
l->lock.rw_blocked_readers = 0;
l->lock.rw_blocked_writers = 0;
}
if ((state & URWLOCK_WRITE_OWNER) != 0) {
if (l->rlocks > 0) {
l->rlocks--;
return;
} else {
l->wowner = NULL;
}
}
if (_thr_rwlock_unlock(&l->lock) == 0) {
if ((state & URWLOCK_WRITE_OWNER) == 0)
curthread->rdlock_count--;