Change the sx(9) assertion API to use a sx_assert() function similar to
mtx_assert(9) rather than several SX_ASSERT_* macros.
This commit is contained in:
parent
e5e5b51f9f
commit
4e5e677bc0
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=85388
@ -671,7 +671,7 @@ proc_reparent(child, parent)
|
||||
register struct proc *parent;
|
||||
{
|
||||
|
||||
SX_ASSERT_XLOCKED(&proctree_lock);
|
||||
sx_assert(&proctree_lock, SX_XLOCKED);
|
||||
PROC_LOCK_ASSERT(child, MA_OWNED);
|
||||
if (child->p_pptr == parent)
|
||||
return;
|
||||
|
@ -197,8 +197,8 @@ void
|
||||
_sx_sunlock(struct sx *sx, const char *file, int line)
|
||||
{
|
||||
|
||||
_sx_assert(sx, SX_SLOCKED, file, line);
|
||||
mtx_lock(&sx->sx_lock);
|
||||
_SX_ASSERT_SLOCKED(sx, file, line);
|
||||
|
||||
WITNESS_UNLOCK(&sx->sx_object, 0, file, line);
|
||||
|
||||
@ -226,8 +226,8 @@ void
|
||||
_sx_xunlock(struct sx *sx, const char *file, int line)
|
||||
{
|
||||
|
||||
_sx_assert(sx, SX_XLOCKED, file, 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);
|
||||
@ -253,8 +253,8 @@ int
|
||||
_sx_try_upgrade(struct sx *sx, const char *file, int line)
|
||||
{
|
||||
|
||||
_sx_assert(sx, SX_SLOCKED, file, line);
|
||||
mtx_lock(&sx->sx_lock);
|
||||
_SX_ASSERT_SLOCKED(sx, file, line);
|
||||
|
||||
if (sx->sx_cnt == 1) {
|
||||
sx->sx_cnt = -1;
|
||||
@ -277,8 +277,8 @@ void
|
||||
_sx_downgrade(struct sx *sx, const char *file, int line)
|
||||
{
|
||||
|
||||
_sx_assert(sx, SX_XLOCKED, file, line);
|
||||
mtx_lock(&sx->sx_lock);
|
||||
_SX_ASSERT_XLOCKED(sx, file, line);
|
||||
MPASS(sx->sx_cnt == -1);
|
||||
|
||||
WITNESS_DOWNGRADE(&sx->sx_object, 0, file, line);
|
||||
@ -292,3 +292,42 @@ _sx_downgrade(struct sx *sx, const char *file, int line)
|
||||
|
||||
mtx_unlock(&sx->sx_lock);
|
||||
}
|
||||
|
||||
#ifdef INVARIANT_SUPPORT
|
||||
/*
|
||||
* In the non-WITNESS case, sx_assert() can only detect that at least
|
||||
* *some* thread owns an slock, but it cannot guarantee that *this*
|
||||
* thread owns an slock.
|
||||
*/
|
||||
void
|
||||
_sx_assert(struct sx *sx, int what, const char *file, int line)
|
||||
{
|
||||
|
||||
switch (what) {
|
||||
case SX_LOCKED:
|
||||
case SX_SLOCKED:
|
||||
#ifdef WITNESS
|
||||
witness_assert(&sx->sx_object, what, file, line);
|
||||
#else
|
||||
mtx_lock(&sx->sx_lock);
|
||||
if (sx->sx_cnt <= 0 &&
|
||||
(what == SX_SLOCKED || sx->sx_xholder == curthread))
|
||||
printf("Lock %s not %slocked @ %s:%d",
|
||||
sx->sx_object.lo_name, (what == SX_SLOCKED) ?
|
||||
"share " : "", file, line);
|
||||
mtx_unlock(&sx->sx_lock);
|
||||
#endif
|
||||
break;
|
||||
case SX_XLOCKED:
|
||||
mtx_lock(&sx->sx_lock);
|
||||
if (sx->sx_xholder != curthread)
|
||||
printf("Lock %s not exclusively locked @ %s:%d",
|
||||
sx->sx_object.lo_name, file, line);
|
||||
mtx_unlock(&sx->sx_lock);
|
||||
break;
|
||||
default:
|
||||
panic("Unknown sx lock assertion: %d @ %s:%d", what, file,
|
||||
line);
|
||||
}
|
||||
}
|
||||
#endif /* INVARIANT_SUPPORT */
|
||||
|
45
sys/sys/sx.h
45
sys/sys/sx.h
@ -57,6 +57,9 @@ 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);
|
||||
#ifdef INVARIANT_SUPPORT
|
||||
void _sx_assert(struct sx *sx, int what, const char *file, int line);
|
||||
#endif
|
||||
|
||||
#define sx_slock(sx) _sx_slock((sx), LOCK_FILE, LOCK_LINE)
|
||||
#define sx_xlock(sx) _sx_xlock((sx), LOCK_FILE, LOCK_LINE)
|
||||
@ -68,45 +71,13 @@ void _sx_downgrade(struct sx *sx, const char *file, int line);
|
||||
#define sx_downgrade(sx) _sx_downgrade((sx), LOCK_FILE, LOCK_LINE)
|
||||
|
||||
#ifdef INVARIANTS
|
||||
/*
|
||||
* In the non-WITNESS case, SX_ASSERT_LOCKED() and SX_ASSERT_SLOCKED()
|
||||
* can only detect that at least *some* thread owns an slock, but it cannot
|
||||
* guarantee that *this* thread owns an slock.
|
||||
*/
|
||||
#ifdef WITNESS
|
||||
#define _SX_ASSERT_LOCKED(sx, file, line) \
|
||||
witness_assert(&(sx)->sx_object, LA_LOCKED, file, line)
|
||||
#define _SX_ASSERT_SLOCKED(sx, file, line) \
|
||||
witness_assert(&(sx)->sx_object, LA_SLOCKED, file, line)
|
||||
#else
|
||||
#define _SX_ASSERT_LOCKED(sx, file, line) do { \
|
||||
KASSERT(((sx)->sx_cnt > 0 || (sx)->sx_xholder == curthread), \
|
||||
("Lock %s not locked @ %s:%d", (sx)->sx_object.lo_name, \
|
||||
file, line)); \
|
||||
} while (0)
|
||||
#define _SX_ASSERT_SLOCKED(sx, file, line) do { \
|
||||
KASSERT(((sx)->sx_cnt > 0), ("Lock %s not share locked @ %s:%d",\
|
||||
(sx)->sx_object.lo_name, file, line)); \
|
||||
} while (0)
|
||||
#endif
|
||||
#define SX_ASSERT_LOCKED(sx) _SX_ASSERT_LOCKED((sx), LOCK_FILE, LOCK_LINE)
|
||||
#define SX_ASSERT_SLOCKED(sx) _SX_ASSERT_SLOCKED((sx), LOCK_FILE, LOCK_LINE)
|
||||
|
||||
/*
|
||||
* SX_ASSERT_XLOCKED() detects and guarantees that *we* own the xlock.
|
||||
*/
|
||||
#define _SX_ASSERT_XLOCKED(sx, file, line) do { \
|
||||
KASSERT(((sx)->sx_xholder == curthread), \
|
||||
("Lock %s not exclusively locked @ %s:%d", \
|
||||
(sx)->sx_object.lo_name, file, line)); \
|
||||
} while (0)
|
||||
#define SX_ASSERT_XLOCKED(sx) _SX_ASSERT_XLOCKED((sx), LOCK_FILE, LOCK_LINE)
|
||||
#define SX_LOCKED LA_LOCKED
|
||||
#define SX_SLOCKED LA_SLOCKED
|
||||
#define SX_XLOCKED LA_XLOCKED
|
||||
|
||||
#define sx_assert(sx, what) _sx_assert((sx), (what), LOCK_FILE, LOCK_LINE)
|
||||
#else /* INVARIANTS */
|
||||
#define SX_ASSERT_SLOCKED(sx)
|
||||
#define SX_ASSERT_XLOCKED(sx)
|
||||
#define _SX_ASSERT_SLOCKED(sx, file, line)
|
||||
#define _SX_ASSERT_XLOCKED(sx, file, line)
|
||||
#define sx_assert(sx, what)
|
||||
#endif /* INVARIANTS */
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
Loading…
Reference in New Issue
Block a user