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:
@@ -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--;
|
||||
|
||||
Reference in New Issue
Block a user