Fix INVARIANTS support

This commit is contained in:
Sebastian Huber
2017-05-18 09:35:46 +02:00
parent 5be4f06fa8
commit 62c8ca0ead
10 changed files with 138 additions and 195 deletions

View File

@@ -209,18 +209,32 @@ rtems_bsd_mutex_unlock(rtems_bsd_mutex *m)
}
}
static inline int
rtems_bsd_mutex_owned(rtems_bsd_mutex *m)
static inline Thread_Control *
rtems_bsd_mutex_owner(const rtems_bsd_mutex *m)
{
return (m->queue.Queue.owner == _Thread_Get_executing());
return (m->queue.Queue.owner);
}
static inline int
rtems_bsd_mutex_recursed(rtems_bsd_mutex *m)
rtems_bsd_mutex_owned(const rtems_bsd_mutex *m)
{
return (m->nest_level);
return (rtems_bsd_mutex_owner(m) == _Thread_Get_executing());
}
static inline int
rtems_bsd_mutex_recursed(const rtems_bsd_mutex *m)
{
return (m->nest_level != 0);
}
static inline const char *
rtems_bsd_mutex_name(const rtems_bsd_mutex *m)
{
return (m->queue.Queue.name);
}
static inline void

View File

@@ -164,33 +164,30 @@ _mtx_unlock_flags(struct mtx *m, int opts, const char *file, int line)
void
_mtx_assert(struct mtx *m, int what, const char *file, int line)
{
const char *name = rtems_bsd_mutex_name(&m->mutex);
if (panicstr != NULL || dumping)
return;
switch (what) {
case MA_OWNED:
case MA_OWNED | MA_RECURSED:
case MA_OWNED | MA_NOTRECURSED:
if (!mtx_owned(m))
panic("mutex %s not owned at %s:%d",
m->lock_object.lo_name, file, line);
if (mtx_recursed(m)) {
if ((what & MA_NOTRECURSED) != 0)
panic("mutex %s recursed at %s:%d",
m->lock_object.lo_name, file, line);
} else if ((what & MA_RECURSED) != 0) {
panic("mutex %s unrecursed at %s:%d",
m->lock_object.lo_name, file, line);
}
break;
case MA_NOTOWNED:
if (mtx_owned(m))
panic("mutex %s owned at %s:%d",
m->lock_object.lo_name, file, line);
break;
default:
panic("unknown mtx_assert at %s:%d", file, line);
}
switch (what) {
case MA_OWNED:
case MA_OWNED | MA_RECURSED:
case MA_OWNED | MA_NOTRECURSED:
if (!mtx_owned(m))
panic("mutex %s not owned at %s:%d", name, file, line);
if (mtx_recursed(m)) {
if ((what & MA_NOTRECURSED) != 0)
panic("mutex %s recursed at %s:%d", name, file,
line);
} else if ((what & MA_RECURSED) != 0) {
panic("mutex %s unrecursed at %s:%d", name, file,
line);
}
break;
case MA_NOTOWNED:
if (mtx_owned(m))
panic("mutex %s owned at %s:%d", name, file, line);
break;
default:
panic("unknown mtx_assert at %s:%d", file, line);
}
}
#endif

View File

@@ -79,9 +79,9 @@ struct lock_class lock_class_rw = {
#endif
};
#define rw_wowner(rw) ((rw)->mutex.owner)
#define rw_wowner(rw) rtems_bsd_mutex_owner(&(rw)->mutex)
#define rw_recursed(rw) ((rw)->mutex.nest_level != 0)
#define rw_recursed(rw) rtems_bsd_mutex_recursed(&(rw)->mutex)
void
assert_rw(struct lock_object *lock, int what)
@@ -207,87 +207,53 @@ _rw_downgrade(struct rwlock *rw, const char *file, int line)
}
#ifdef INVARIANT_SUPPORT
#ifndef INVARIANTS
#undef _rw_assert
#endif
/*
* In the non-WITNESS case, rw_assert() can only detect that at least
* *some* thread owns an rlock, but it cannot guarantee that *this*
* thread owns an rlock.
*/
void
_rw_assert(struct rwlock *rw, int what, const char *file, int line)
_rw_assert(const struct rwlock *rw, int what, const char *file, int line)
{
const char *name = rtems_bsd_mutex_name(&rw->mutex);
if (panicstr != NULL)
return;
switch (what) {
case RA_LOCKED:
case RA_LOCKED | RA_RECURSED:
case RA_LOCKED | RA_NOTRECURSED:
case RA_RLOCKED:
#ifndef __rtems__
switch (what) {
case RA_LOCKED:
case RA_LOCKED | RA_RECURSED:
case RA_LOCKED | RA_NOTRECURSED:
case RA_RLOCKED:
case RA_RLOCKED | RA_RECURSED:
case RA_RLOCKED | RA_NOTRECURSED:
case RA_WLOCKED:
case RA_WLOCKED | RA_RECURSED:
case RA_WLOCKED | RA_NOTRECURSED:
if (rw_wowner(rw) != _Thread_Get_executing())
panic("Lock %s not exclusively locked @ %s:%d\n",
name, file, line);
if (rw_recursed(rw)) {
if (what & RA_NOTRECURSED)
panic("Lock %s recursed @ %s:%d\n", name, file,
line);
} else if (what & RA_RECURSED)
panic("Lock %s not recursed @ %s:%d\n", name, file,
line);
break;
case RA_UNLOCKED:
#ifdef WITNESS
witness_assert(&rw->lock_object, what, file, line);
witness_assert(&rw->lock_object, what, file, line);
#else
/*
* If some other thread has a write lock or we have one
* and are asserting a read lock, fail. Also, if no one
* has a lock at all, fail.
*/
if (rw->rw_lock == RW_UNLOCKED ||
(!(rw->rw_lock & RW_LOCK_READ) && (what == RA_RLOCKED ||
rw_wowner(rw) != curthread)))
panic("Lock %s not %slocked @ %s:%d\n",
rw->lock_object.lo_name, (what == RA_RLOCKED) ?
"read " : "", file, line);
if (!(rw->rw_lock & RW_LOCK_READ)) {
if (rw_recursed(rw)) {
if (what & RA_NOTRECURSED)
panic("Lock %s recursed @ %s:%d\n",
rw->lock_object.lo_name, file,
line);
} else if (what & RA_RECURSED)
panic("Lock %s not recursed @ %s:%d\n",
rw->lock_object.lo_name, file, line);
}
/*
* If we hold a write lock fail. We can't reliably check
* to see if we hold a read lock or not.
*/
if (rw_wowner(rw) == _Thread_Get_executing())
panic("Lock %s exclusively locked @ %s:%d\n", name,
file, line);
#endif
break;
#else /* __rtems__ */
/* FALLTHROUGH */
#endif /* __rtems__ */
case RA_WLOCKED:
case RA_WLOCKED | RA_RECURSED:
case RA_WLOCKED | RA_NOTRECURSED:
if (rw_wowner(rw) != _Thread_Get_executing())
panic("Lock %s not exclusively locked @ %s:%d\n",
rw->lock_object.lo_name, file, line);
if (rw_recursed(rw)) {
if (what & RA_NOTRECURSED)
panic("Lock %s recursed @ %s:%d\n",
rw->lock_object.lo_name, file, line);
} else if (what & RA_RECURSED)
panic("Lock %s not recursed @ %s:%d\n",
rw->lock_object.lo_name, file, line);
break;
case RA_UNLOCKED:
#ifdef WITNESS
witness_assert(&rw->lock_object, what, file, line);
#else
/*
* If we hold a write lock fail. We can't reliably check
* to see if we hold a read lock or not.
*/
if (rw_wowner(rw) == _Thread_Get_executing())
panic("Lock %s exclusively locked @ %s:%d\n",
rw->lock_object.lo_name, file, line);
#endif
break;
default:
panic("Unknown rw lock assertion: %d @ %s:%d", what, file,
line);
}
break;
default:
panic("Unknown rw lock assertion: %d @ %s:%d", what, file,
line);
}
}
#endif /* INVARIANT_SUPPORT */

View File

@@ -47,10 +47,6 @@
#include <sys/lock.h>
#include <sys/sx.h>
#ifndef INVARIANTS
#define _sx_assert(sx, what, file, line)
#endif
static void assert_sx(struct lock_object *lock, int what);
static void lock_sx(struct lock_object *lock, int how);
#ifdef KDTRACE_HOOKS
@@ -72,9 +68,9 @@ struct lock_class lock_class_sx = {
#endif
};
#define sx_xholder(sx) ((sx)->mutex.owner)
#define sx_xholder(sx) rtems_bsd_mutex_owner(&(sx)->mutex)
#define sx_recursed(sx) ((sx)->mutex.nest_level != 0)
#define sx_recursed(sx) rtems_bsd_mutex_recursed(&(sx)->mutex)
void
assert_sx(struct lock_object *lock, int what)
@@ -170,102 +166,55 @@ sx_downgrade_(struct sx *sx, const char *file, int line)
}
#ifdef INVARIANT_SUPPORT
#ifndef INVARIANTS
#undef _sx_assert
#endif
/*
* 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)
_sx_assert(const struct sx *sx, int what, const char *file, int line)
{
#ifndef __rtems__
#ifndef WITNESS
int slocked = 0;
#endif
#endif /* __rtems__ */
const char *name = rtems_bsd_mutex_name(&sx->mutex);
if (panicstr != NULL)
return;
switch (what) {
case SA_SLOCKED:
case SA_SLOCKED | SA_NOTRECURSED:
case SA_SLOCKED | SA_RECURSED:
#ifndef __rtems__
#ifndef WITNESS
slocked = 1;
/* FALLTHROUGH */
#endif
#endif /* __rtems__ */
case SA_LOCKED:
case SA_LOCKED | SA_NOTRECURSED:
case SA_LOCKED | SA_RECURSED:
#ifndef __rtems__
switch (what) {
case SA_SLOCKED:
case SA_SLOCKED | SA_NOTRECURSED:
case SA_SLOCKED | SA_RECURSED:
case SA_LOCKED:
case SA_LOCKED | SA_NOTRECURSED:
case SA_LOCKED | SA_RECURSED:
case SA_XLOCKED:
case SA_XLOCKED | SA_NOTRECURSED:
case SA_XLOCKED | SA_RECURSED:
if (sx_xholder(sx) != _Thread_Get_executing())
panic("Lock %s not exclusively locked @ %s:%d\n", name,
file, line);
if (sx_recursed(sx)) {
if (what & SA_NOTRECURSED)
panic("Lock %s recursed @ %s:%d\n", name, file,
line);
} else if (what & SA_RECURSED)
panic("Lock %s not recursed @ %s:%d\n", name, file,
line);
break;
case SA_UNLOCKED:
#ifdef WITNESS
witness_assert(&sx->lock_object, what, file, line);
witness_assert(&sx->lock_object, what, file, line);
#else
/*
* If some other thread has an exclusive lock or we
* have one and are asserting a shared lock, fail.
* Also, if no one has a lock at all, fail.
*/
if (sx->sx_lock == SX_LOCK_UNLOCKED ||
(!(sx->sx_lock & SX_LOCK_SHARED) && (slocked ||
sx_xholder(sx) != curthread)))
panic("Lock %s not %slocked @ %s:%d\n",
sx->lock_object.lo_name, slocked ? "share " : "",
file, line);
if (!(sx->sx_lock & SX_LOCK_SHARED)) {
if (sx_recursed(sx)) {
if (what & SA_NOTRECURSED)
panic("Lock %s recursed @ %s:%d\n",
sx->lock_object.lo_name, file,
line);
} else if (what & SA_RECURSED)
panic("Lock %s not recursed @ %s:%d\n",
sx->lock_object.lo_name, file, line);
}
/*
* If we hold an exclusve lock fail. We can't
* reliably check to see if we hold a shared lock or
* not.
*/
if (sx_xholder(sx) == _Thread_Get_executing())
panic("Lock %s exclusively locked @ %s:%d\n", name,
file, line);
#endif
break;
#else /* __rtems__ */
/* FALLTHROUGH */
#endif /* __rtems__ */
case SA_XLOCKED:
case SA_XLOCKED | SA_NOTRECURSED:
case SA_XLOCKED | SA_RECURSED:
if (sx_xholder(sx) != _Thread_Get_executing())
panic("Lock %s not exclusively locked @ %s:%d\n",
sx->lock_object.lo_name, file, line);
if (sx_recursed(sx)) {
if (what & SA_NOTRECURSED)
panic("Lock %s recursed @ %s:%d\n",
sx->lock_object.lo_name, file, line);
} else if (what & SA_RECURSED)
panic("Lock %s not recursed @ %s:%d\n",
sx->lock_object.lo_name, file, line);
break;
case SA_UNLOCKED:
#ifdef WITNESS
witness_assert(&sx->lock_object, what, file, line);
#else
/*
* If we hold an exclusve lock fail. We can't
* reliably check to see if we hold a shared lock or
* not.
*/
if (sx_xholder(sx) == _Thread_Get_executing())
panic("Lock %s exclusively locked @ %s:%d\n",
sx->lock_object.lo_name, file, line);
#endif
break;
default:
panic("Unknown sx lock assertion: %d @ %s:%d", what, file,
line);
}
break;
default:
panic("Unknown sx lock assertion: %d @ %s:%d", what, file,
line);
}
}
#endif /* INVARIANT_SUPPORT */