diff options
author | mjg <mjg@FreeBSD.org> | 2016-12-31 16:37:47 +0000 |
---|---|---|
committer | mjg <mjg@FreeBSD.org> | 2016-12-31 16:37:47 +0000 |
commit | 4d5f81f319b8c07d6c5caff90308903ca20a6668 (patch) | |
tree | 4326353ab58864342ca1345f0d4c12b8891f25e5 /sys/kern/kern_sx.c | |
parent | f3626becbf8107ecc4188b9c807fa02b06527c46 (diff) | |
download | FreeBSD-src-4d5f81f319b8c07d6c5caff90308903ca20a6668.zip FreeBSD-src-4d5f81f319b8c07d6c5caff90308903ca20a6668.tar.gz |
MFC r301157:
Microoptimize locking primitives by avoiding unnecessary atomic ops.
Inline version of primitives do an atomic op and if it fails they fallback to
actual primitives, which immediately retry the atomic op.
The obvious optimisation is to check if the lock is free and only then proceed
to do an atomic op.
Diffstat (limited to 'sys/kern/kern_sx.c')
-rw-r--r-- | sys/kern/kern_sx.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/sys/kern/kern_sx.c b/sys/kern/kern_sx.c index 952f7d4..3ba482b 100644 --- a/sys/kern/kern_sx.c +++ b/sys/kern/kern_sx.c @@ -547,7 +547,10 @@ _sx_xlock_hard(struct sx *sx, uintptr_t tid, int opts, const char *file, all_time -= lockstat_nsecs(&sx->lock_object); state = sx->sx_lock; #endif - while (!atomic_cmpset_acq_ptr(&sx->sx_lock, SX_LOCK_UNLOCKED, tid)) { + for (;;) { + if (sx->sx_lock == SX_LOCK_UNLOCKED && + atomic_cmpset_acq_ptr(&sx->sx_lock, SX_LOCK_UNLOCKED, tid)) + break; #ifdef KDTRACE_HOOKS spin_cnt++; #endif |