Add simple_lock_assert_locked/simple_lock_assert_unlocked to provide additional
useful information when panic'ing because the assertion fails. Use these to define the SCHED_ASSERT_LOCKED/SCHED_ASSERT_UNLOCKED macros.
This commit is contained in:
parent
625f1bbe61
commit
e4412d2162
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_lock.c,v 1.93 2006/03/16 00:52:32 erh Exp $ */
|
||||
/* $NetBSD: kern_lock.c,v 1.94 2006/03/26 20:19:52 erh Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
|
||||
|
@ -76,7 +76,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_lock.c,v 1.93 2006/03/16 00:52:32 erh Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_lock.c,v 1.94 2006/03/26 20:19:52 erh Exp $");
|
||||
|
||||
#include "opt_multiprocessor.h"
|
||||
#include "opt_lockdebug.h"
|
||||
|
@ -1367,6 +1367,45 @@ simple_lock_only_held(volatile struct simplelock *lp, const char *where)
|
|||
SLOCK_DEBUGGER();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set to 1 by simple_lock_assert_*().
|
||||
* Can be cleared from ddb to avoid a panic.
|
||||
*/
|
||||
int slock_assert_will_panic;
|
||||
|
||||
/*
|
||||
* If the lock isn't held, print a traceback, optionally drop into the
|
||||
* debugger, then panic.
|
||||
* The panic can be avoided by clearing slock_assert_with_panic from the
|
||||
* debugger.
|
||||
*/
|
||||
void
|
||||
_simple_lock_assert_locked(volatile struct simplelock *alp,
|
||||
const char *lockname, const char *id, int l)
|
||||
{
|
||||
if (simple_lock_held(alp) == 0) {
|
||||
slock_assert_will_panic = 1;
|
||||
lock_printf("%s lock not held\n", lockname);
|
||||
SLOCK_WHERE("lock not held", alp, id, l);
|
||||
if (slock_assert_will_panic)
|
||||
panic("%s: not locked", lockname);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_simple_lock_assert_unlocked(volatile struct simplelock *alp,
|
||||
const char *lockname, const char *id, int l)
|
||||
{
|
||||
if (simple_lock_held(alp)) {
|
||||
slock_assert_will_panic = 1;
|
||||
lock_printf("%s lock held\n", lockname);
|
||||
SLOCK_WHERE("lock held", alp, id, l);
|
||||
if (slock_assert_will_panic)
|
||||
panic("%s: locked", lockname);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* LOCKDEBUG */ /* } */
|
||||
|
||||
#if defined(MULTIPROCESSOR)
|
||||
|
@ -1495,8 +1534,8 @@ _kernel_lock_acquire_count(int hold_count)
|
|||
void
|
||||
_kernel_lock_assert_locked()
|
||||
{
|
||||
|
||||
LOCK_ASSERT(simple_lock_held(&kernel_lock));
|
||||
_simple_lock_assert_locked(&kernel_lock, "kernel_lock");
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MULTIPROCESSOR */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: lock.h,v 1.63 2006/01/02 21:53:30 uwe Exp $ */
|
||||
/* $NetBSD: lock.h,v 1.64 2006/03/26 20:19:52 erh Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
|
||||
|
@ -327,22 +327,32 @@ void _spinlock_acquire_count(volatile struct lock *, int, const char *,
|
|||
#define spinlock_release_all(l) _spinlock_release_all((l), __FILE__, __LINE__)
|
||||
#define spinlock_acquire_count(l, c) _spinlock_acquire_count((l), (c), \
|
||||
__FILE__, __LINE__)
|
||||
|
||||
#else
|
||||
int spinlock_release_all(volatile struct lock *);
|
||||
void spinlock_acquire_count(volatile struct lock *, int);
|
||||
#endif
|
||||
|
||||
#if defined(LOCKDEBUG)
|
||||
|
||||
void _simple_lock(volatile struct simplelock *, const char *, int);
|
||||
int _simple_lock_try(volatile struct simplelock *, const char *, int);
|
||||
void _simple_unlock(volatile struct simplelock *, const char *, int);
|
||||
int _simple_lock_held(volatile struct simplelock *);
|
||||
void simple_lock_only_held(volatile struct simplelock *, const char *);
|
||||
void _simple_lock_assert_locked(volatile struct simplelock *, const char *,
|
||||
const char *, int l);
|
||||
void _simple_lock_assert_unlocked(volatile struct simplelock *, const char *,
|
||||
const char *, int l);
|
||||
|
||||
#define simple_lock(alp) _simple_lock((alp), __FILE__, __LINE__)
|
||||
#define simple_lock_try(alp) _simple_lock_try((alp), __FILE__, __LINE__)
|
||||
#define simple_unlock(alp) _simple_unlock((alp), __FILE__, __LINE__)
|
||||
#define simple_lock_held(alp) _simple_lock_held((alp))
|
||||
#define simple_lock_assert_locked(alp,lockname) \
|
||||
_simple_lock_assert_locked((alp),(lockname), __FILE__, __LINE__)
|
||||
#define simple_lock_assert_unlocked(alp,lockname) \
|
||||
_simple_lock_assert_unlocked((alp),(lockname), __FILE__, __LINE__)
|
||||
|
||||
#define LOCK_ASSERT(x) KASSERT(x)
|
||||
|
||||
|
@ -357,17 +367,23 @@ void simple_lock_switchcheck(void);
|
|||
#define simple_unlock(alp) __cpu_simple_unlock(&(alp)->lock_data)
|
||||
#define LOCK_ASSERT(x) /* nothing */
|
||||
#define simple_lock_only_held(x,y) /* nothing */
|
||||
#define simple_lock_assert_locked(alp,lockname) /* nothing */
|
||||
#define simple_lock_assert_unlocked(alp,lockname) /* nothing */
|
||||
#else
|
||||
#define simple_lock_try(alp) (1)
|
||||
#ifndef __lint__
|
||||
#define simple_lock_init(alp) (void)(alp)
|
||||
#define simple_lock(alp) (void)(alp)
|
||||
#define simple_unlock(alp) (void)(alp)
|
||||
#define simple_lock_assert_locked(alp,lockname) (void)(alp)
|
||||
#define simple_lock_assert_unlocked(alp,lockname) (void)(alp)
|
||||
#else /* __lint__ */
|
||||
#define simple_lock_init(alp) /* nothing */
|
||||
#define simple_lock(alp) /* nothing */
|
||||
#define simple_unlock(alp) /* nothing */
|
||||
#define simple_lock_only_held(x,y) /* nothing */
|
||||
#define simple_lock_assert_locked(alp,lockname) /* nothing */
|
||||
#define simple_lock_assert_unlocked(alp,lockname) /* nothing */
|
||||
#endif /* __lint__ */
|
||||
#define LOCK_ASSERT(x) /* nothing */
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sched.h,v 1.26 2005/12/26 18:41:36 perry Exp $ */
|
||||
/* $NetBSD: sched.h,v 1.27 2006/03/26 20:19:52 erh Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000, 2001, 2002 The NetBSD Foundation, Inc.
|
||||
|
@ -201,8 +201,9 @@ void scheduler_wait_hook(struct proc *, struct proc *);
|
|||
|
||||
extern struct simplelock sched_lock;
|
||||
|
||||
#define SCHED_ASSERT_LOCKED() LOCK_ASSERT(simple_lock_held(&sched_lock))
|
||||
#define SCHED_ASSERT_UNLOCKED() LOCK_ASSERT(simple_lock_held(&sched_lock) == 0)
|
||||
#define SCHED_ASSERT_LOCKED() simple_lock_assert_locked(&sched_lock, "sched_lock")
|
||||
#define SCHED_ASSERT_UNLOCKED() simple_lock_assert_unlocked(&sched_lock, "sched_lock")
|
||||
|
||||
|
||||
#define SCHED_LOCK(s) \
|
||||
do { \
|
||||
|
|
Loading…
Reference in New Issue