Changeset View
Changeset View
Standalone View
Standalone View
sys/sys/sx.h
Show First 20 Lines • Show All 147 Lines • ▼ Show 20 Lines | __sx_xlock(struct sx *sx, struct thread *td, int opts, const char *file, | ||||
int line) | int line) | ||||
{ | { | ||||
uintptr_t tid = (uintptr_t)td; | uintptr_t tid = (uintptr_t)td; | ||||
int error = 0; | int error = 0; | ||||
if (!atomic_cmpset_acq_ptr(&sx->sx_lock, SX_LOCK_UNLOCKED, tid)) | if (!atomic_cmpset_acq_ptr(&sx->sx_lock, SX_LOCK_UNLOCKED, tid)) | ||||
error = _sx_xlock_hard(sx, tid, opts, file, line); | error = _sx_xlock_hard(sx, tid, opts, file, line); | ||||
else | else | ||||
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_SX_XLOCK_ACQUIRE, | LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(sx__acquire, | ||||
sx, 0, 0, file, line); | sx, 0, 0, file, line, 0); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* Release an exclusive lock. */ | /* Release an exclusive lock. */ | ||||
static __inline void | static __inline void | ||||
__sx_xunlock(struct sx *sx, struct thread *td, const char *file, int line) | __sx_xunlock(struct sx *sx, struct thread *td, const char *file, int line) | ||||
{ | { | ||||
uintptr_t tid = (uintptr_t)td; | uintptr_t tid = (uintptr_t)td; | ||||
if (sx->sx_recurse == 0) | if (sx->sx_recurse == 0) | ||||
LOCKSTAT_PROFILE_RELEASE_LOCK(LS_SX_XUNLOCK_RELEASE, sx); | LOCKSTAT_PROFILE_RELEASE_LOCK(sx__release, sx, 0); | ||||
if (!atomic_cmpset_rel_ptr(&sx->sx_lock, tid, SX_LOCK_UNLOCKED)) | if (!atomic_cmpset_rel_ptr(&sx->sx_lock, tid, SX_LOCK_UNLOCKED)) | ||||
_sx_xunlock_hard(sx, tid, file, line); | _sx_xunlock_hard(sx, tid, file, line); | ||||
} | } | ||||
/* Acquire a shared lock. */ | /* Acquire a shared lock. */ | ||||
static __inline int | static __inline int | ||||
__sx_slock(struct sx *sx, int opts, const char *file, int line) | __sx_slock(struct sx *sx, int opts, const char *file, int line) | ||||
{ | { | ||||
uintptr_t x = sx->sx_lock; | uintptr_t x = sx->sx_lock; | ||||
int error = 0; | int error = 0; | ||||
if (!(x & SX_LOCK_SHARED) || | if (!(x & SX_LOCK_SHARED) || | ||||
!atomic_cmpset_acq_ptr(&sx->sx_lock, x, x + SX_ONE_SHARER)) | !atomic_cmpset_acq_ptr(&sx->sx_lock, x, x + SX_ONE_SHARER)) | ||||
error = _sx_slock_hard(sx, opts, file, line); | error = _sx_slock_hard(sx, opts, file, line); | ||||
else | else | ||||
LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(LS_SX_SLOCK_ACQUIRE, sx, 0, | LOCKSTAT_PROFILE_OBTAIN_LOCK_SUCCESS(sx__acquire, sx, 0, | ||||
0, file, line); | 0, file, line, 0); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Release a shared lock. We can just drop a single shared lock so | * Release a shared lock. We can just drop a single shared lock so | ||||
* long as we aren't trying to drop the last shared lock when other | * long as we aren't trying to drop the last shared lock when other | ||||
* threads are waiting for an exclusive lock. This takes advantage of | * threads are waiting for an exclusive lock. This takes advantage of | ||||
* the fact that an unlocked lock is encoded as a shared lock with a | * the fact that an unlocked lock is encoded as a shared lock with a | ||||
* count of 0. | * count of 0. | ||||
*/ | */ | ||||
static __inline void | static __inline void | ||||
__sx_sunlock(struct sx *sx, const char *file, int line) | __sx_sunlock(struct sx *sx, const char *file, int line) | ||||
{ | { | ||||
uintptr_t x = sx->sx_lock; | uintptr_t x = sx->sx_lock; | ||||
LOCKSTAT_PROFILE_RELEASE_LOCK(LS_SX_SUNLOCK_RELEASE, sx); | LOCKSTAT_PROFILE_RELEASE_LOCK(sx__release, sx, 0); | ||||
if (x == (SX_SHARERS_LOCK(1) | SX_LOCK_EXCLUSIVE_WAITERS) || | if (x == (SX_SHARERS_LOCK(1) | SX_LOCK_EXCLUSIVE_WAITERS) || | ||||
!atomic_cmpset_rel_ptr(&sx->sx_lock, x, x - SX_ONE_SHARER)) | !atomic_cmpset_rel_ptr(&sx->sx_lock, x, x - SX_ONE_SHARER)) | ||||
_sx_sunlock_hard(sx, file, line); | _sx_sunlock_hard(sx, file, line); | ||||
} | } | ||||
/* | /* | ||||
* Public interface for lock operations. | * Public interface for lock operations. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 110 Lines • Show Last 20 Lines |