Add sx_try_upgrade() and sx_downgrade().

Submitted by:	Alexander Kabaev <ak03@gte.com>
This commit is contained in:
Jason Evans 2001-08-13 21:25:30 +00:00
parent 9c347fa626
commit d55229b72e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=81599
4 changed files with 69 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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
/*