Add sx_try_upgrade() and sx_downgrade().
Submitted by: Alexander Kabaev <ak03@gte.com>
This commit is contained in:
parent
9c347fa626
commit
d55229b72e
@ -169,6 +169,8 @@ MLINKS+=sx.9 sx_try_slock.9
|
||||
MLINKS+=sx.9 sx_try_xlock.9
|
||||
MLINKS+=sx.9 sx_sunlock.9
|
||||
MLINKS+=sx.9 sx_xunlock.9
|
||||
MLINKS+=sx.9 sx_try_upgrade.9
|
||||
MLINKS+=sx.9 sx_downgrade.9
|
||||
MLINKS+=time.9 boottime.9 time.9 mono_time.9 time.9 runtime.9
|
||||
MLINKS+=timeout.9 untimeout.9
|
||||
MLINKS+=timeout.9 callout_handle_init.9 timeout.9 callout_init.9
|
||||
|
@ -39,6 +39,8 @@
|
||||
.Nm sx_try_xlock ,
|
||||
.Nm sx_sunlock ,
|
||||
.Nm sx_xunlock
|
||||
.Nm sx_try_upgrade
|
||||
.Nm sx_downgrade
|
||||
.Nd kernel shared/exclusive lock
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <sys/types.h>
|
||||
@ -61,6 +63,10 @@
|
||||
.Fn sx_sunlock "struct sx *sx"
|
||||
.Ft void
|
||||
.Fn sx_xunlock "struct sx *sx"
|
||||
.Ft int
|
||||
.Fn sx_try_upgrade "struct sx *sx"
|
||||
.Ft void
|
||||
.Fn sx_downgrade "struct sx *sx"
|
||||
.Sh DESCRIPTION
|
||||
Shared/exclusive locks are used to protect data that are read far more often
|
||||
than they are written.
|
||||
@ -91,6 +97,12 @@ or
|
||||
.Fn sx_try_xlock
|
||||
and
|
||||
.Fn sx_xunlock .
|
||||
A thread can attempt to upgrade a currently owned shared lock to an exclusive
|
||||
lock by calling
|
||||
.Fn sx_try_upgrade .
|
||||
A thread that owns an exclusive lock can downgrade it to a shared lock by
|
||||
calling
|
||||
.Fn sx_downgrade .
|
||||
.Pp
|
||||
.Fn sx_try_slock
|
||||
and
|
||||
@ -99,6 +111,11 @@ will return 0 if the shared/exclusive lock cannot be acquired immediately;
|
||||
otherwise the shared/exclusive lock will be acquired and a non-zero value will
|
||||
be returned.
|
||||
.Pp
|
||||
.Fn sx_try_upgrade
|
||||
will return 0 if the shared lock cannot be upgraded to an exclusive lock
|
||||
immediately; otherwise the exclusive lock will be acquired and a non-zero value
|
||||
will be returned.
|
||||
.Pp
|
||||
A thread may not own a shared lock and an exclusive lock simultaneously;
|
||||
attempting to do so will result in deadlock.
|
||||
.Sh SEE ALSO
|
||||
|
@ -245,3 +245,49 @@ _sx_xunlock(struct sx *sx, const char *file, int line)
|
||||
|
||||
mtx_unlock(&sx->sx_lock);
|
||||
}
|
||||
|
||||
int
|
||||
_sx_try_upgrade(struct sx *sx, const char *file, int line)
|
||||
{
|
||||
|
||||
mtx_lock(&sx->sx_lock);
|
||||
_SX_ASSERT_SLOCKED(sx, file, line);
|
||||
|
||||
if (sx->sx_cnt == 1) {
|
||||
WITNESS_UNLOCK(&sx->sx_object, 0, file, line);
|
||||
|
||||
sx->sx_cnt = -1;
|
||||
sx->sx_xholder = curproc;
|
||||
|
||||
LOCK_LOG_TRY("XUPGRADE", &sx->sx_object, 0, 1, file, line);
|
||||
WITNESS_LOCK(&sx->sx_object, LOP_EXCLUSIVE | LOP_TRYLOCK, file,
|
||||
line);
|
||||
|
||||
mtx_unlock(&sx->sx_lock);
|
||||
return (1);
|
||||
} else {
|
||||
LOCK_LOG_TRY("XUPGRADE", &sx->sx_object, 0, 0, file, line);
|
||||
mtx_unlock(&sx->sx_lock);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_sx_downgrade(struct sx *sx, const char *file, int line)
|
||||
{
|
||||
|
||||
mtx_lock(&sx->sx_lock);
|
||||
_SX_ASSERT_XLOCKED(sx, file, line);
|
||||
MPASS(sx->sx_cnt == -1);
|
||||
|
||||
WITNESS_UNLOCK(&sx->sx_object, LOP_EXCLUSIVE, file, line);
|
||||
|
||||
sx->sx_cnt = 1;
|
||||
if (sx->sx_shrd_wcnt > 0)
|
||||
cv_broadcast(&sx->sx_shrd_cv);
|
||||
|
||||
LOCK_LOG_LOCK("XDOWNGRADE", &sx->sx_object, 0, 0, file, line);
|
||||
WITNESS_LOCK(&sx->sx_object, 0, file, line);
|
||||
|
||||
mtx_unlock(&sx->sx_lock);
|
||||
}
|
||||
|
@ -54,6 +54,8 @@ int _sx_try_slock(struct sx *sx, const char *file, int line);
|
||||
int _sx_try_xlock(struct sx *sx, const char *file, int line);
|
||||
void _sx_sunlock(struct sx *sx, const char *file, int line);
|
||||
void _sx_xunlock(struct sx *sx, const char *file, int line);
|
||||
int _sx_try_upgrade(struct sx *sx, const char *file, int line);
|
||||
void _sx_downgrade(struct sx *sx, const char *file, int line);
|
||||
|
||||
#define sx_slock(sx) _sx_slock((sx), __FILE__, __LINE__)
|
||||
#define sx_xlock(sx) _sx_xlock((sx), __FILE__, __LINE__)
|
||||
@ -61,6 +63,8 @@ void _sx_xunlock(struct sx *sx, const char *file, int line);
|
||||
#define sx_try_xlock(sx) _sx_try_xlock((sx), __FILE__, __LINE__)
|
||||
#define sx_sunlock(sx) _sx_sunlock((sx), __FILE__, __LINE__)
|
||||
#define sx_xunlock(sx) _sx_xunlock((sx), __FILE__, __LINE__)
|
||||
#define sx_try_upgrade(sx) _sx_try_upgrade((sx), __FILE__, __LINE__)
|
||||
#define sx_downgrade(sx) _sx_downgrade((sx), __FILE__, __LINE__)
|
||||
|
||||
#ifdef INVARIANTS
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user