aboutsummaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorMateusz Guzik <mjg@FreeBSD.org>2017-02-05 09:54:16 +0000
committerMateusz Guzik <mjg@FreeBSD.org>2017-02-05 09:54:16 +0000
commit6ebb77b6a6dcc1fd13c7ac9f94ab3ec536ce50f5 (patch)
tree6d580299b2242eff129dd2c83b9e3287d86bb3f8 /sys/kern
parentdc0896512cd91cb390cc35ba96e9285cd04383da (diff)
downloadsrc-6ebb77b6a6dcc1fd13c7ac9f94ab3ec536ce50f5.tar.gz
src-6ebb77b6a6dcc1fd13c7ac9f94ab3ec536ce50f5.zip
sx: move lockstat handling out of inline primitives
See r313275 for details.
Notes
Notes: svn path=/head/; revision=313280
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_sx.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/sys/kern/kern_sx.c b/sys/kern/kern_sx.c
index 183726c8e558..4cce16d301b8 100644
--- a/sys/kern/kern_sx.c
+++ b/sys/kern/kern_sx.c
@@ -310,6 +310,7 @@ sx_try_slock_(struct sx *sx, const char *file, int line)
int
_sx_xlock(struct sx *sx, int opts, const char *file, int line)
{
+ uintptr_t tid, x;
int error = 0;
if (SCHEDULER_STOPPED())
@@ -321,7 +322,13 @@ _sx_xlock(struct sx *sx, int opts, const char *file, int line)
("sx_xlock() of destroyed sx @ %s:%d", file, line));
WITNESS_CHECKORDER(&sx->lock_object, LOP_NEWORDER | LOP_EXCLUSIVE, file,
line, NULL);
- error = __sx_xlock(sx, curthread, opts, file, line);
+ tid = (uintptr_t)curthread;
+ x = SX_LOCK_UNLOCKED;
+ if (!atomic_fcmpset_acq_ptr(&sx->sx_lock, &x, tid))
+ error = _sx_xlock_hard(sx, x, tid, opts, file, line);
+ else
+ LOCKSTAT_PROFILE_OBTAIN_RWLOCK_SUCCESS(sx__acquire, sx,
+ 0, 0, file, line, LOCKSTAT_WRITER);
if (!error) {
LOCK_LOG_LOCK("XLOCK", &sx->lock_object, 0, sx->sx_recurse,
file, line);
@@ -379,7 +386,7 @@ _sx_xunlock(struct sx *sx, const char *file, int line)
WITNESS_UNLOCK(&sx->lock_object, LOP_EXCLUSIVE, file, line);
LOCK_LOG_LOCK("XUNLOCK", &sx->lock_object, 0, sx->sx_recurse, file,
line);
- __sx_xunlock(sx, curthread, file, line);
+ _sx_xunlock_hard(sx, (uintptr_t)curthread, file, line);
TD_LOCKS_DEC(curthread);
}
@@ -757,8 +764,13 @@ _sx_xunlock_hard(struct sx *sx, uintptr_t tid, const char *file, int line)
MPASS(!(sx->sx_lock & SX_LOCK_SHARED));
- /* If the lock is recursed, then unrecurse one level. */
- if (sx_xlocked(sx) && sx_recursed(sx)) {
+ if (!sx_recursed(sx)) {
+ LOCKSTAT_PROFILE_RELEASE_RWLOCK(sx__release, sx,
+ LOCKSTAT_WRITER);
+ if (atomic_cmpset_rel_ptr(&sx->sx_lock, tid, SX_LOCK_UNLOCKED))
+ return;
+ } else {
+ /* The lock is recursed, unrecurse one level. */
if ((--sx->sx_recurse) == 0)
atomic_clear_ptr(&sx->sx_lock, SX_LOCK_RECURSED);
if (LOCK_LOG_TEST(&sx->lock_object, 0))