diff options
| author | John Baldwin <jhb@FreeBSD.org> | 2006-01-27 22:24:07 +0000 |
|---|---|---|
| committer | John Baldwin <jhb@FreeBSD.org> | 2006-01-27 22:24:07 +0000 |
| commit | f126e754e00e67f9fb6bbff1542fa2062e8d2ab9 (patch) | |
| tree | 9f7260b793fc191d364e74dae4d8fa68b0221adc /sys/kern/subr_sleepqueue.c | |
| parent | 6966c3348250222dd3b3930f240e3d257f099f13 (diff) | |
Notes
Diffstat (limited to 'sys/kern/subr_sleepqueue.c')
| -rw-r--r-- | sys/kern/subr_sleepqueue.c | 66 |
1 files changed, 64 insertions, 2 deletions
diff --git a/sys/kern/subr_sleepqueue.c b/sys/kern/subr_sleepqueue.c index 8443a7ffeaf2..378fc691eade 100644 --- a/sys/kern/subr_sleepqueue.c +++ b/sys/kern/subr_sleepqueue.c @@ -59,11 +59,12 @@ * variables. */ -#include "opt_sleepqueue_profiling.h" - #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include "opt_sleepqueue_profiling.h" +#include "opt_ddb.h" + #include <sys/param.h> #include <sys/systm.h> #include <sys/lock.h> @@ -77,6 +78,10 @@ __FBSDID("$FreeBSD$"); #include <sys/sleepqueue.h> #include <sys/sysctl.h> +#ifdef DDB +#include <ddb/ddb.h> +#endif + /* * Constants for the hash table of sleep queue chains. These constants are * the same ones that 4BSD (and possibly earlier versions of BSD) used. @@ -842,3 +847,60 @@ sleepq_abort(struct thread *td) sleepq_remove(td, wchan); mtx_lock_spin(&sched_lock); } + +#ifdef DDB +DB_SHOW_COMMAND(sleepq, db_show_sleepqueue) +{ + struct sleepqueue_chain *sc; + struct sleepqueue *sq; + struct lock_object *lock; + struct thread *td; + void *wchan; + int i; + + if (!have_addr) + return; + + /* + * First, see if there is an active sleep queue for the wait channel + * indicated by the address. + */ + wchan = (void *)addr; + sc = SC_LOOKUP(wchan); + LIST_FOREACH(sq, &sc->sc_queues, sq_hash) + if (sq->sq_wchan == wchan) + goto found; + + /* + * Second, see if there is an active sleep queue at the address + * indicated. + */ + for (i = 0; i < SC_TABLESIZE; i++) + LIST_FOREACH(sq, &sleepq_chains[i].sc_queues, sq_hash) { + if (sq == (struct sleepqueue *)addr) + goto found; + } + + db_printf("Unable to locate a sleep queue via %p\n", (void *)addr); + return; +found: + db_printf("Wait channel: %p\n", sq->sq_wchan); +#ifdef INVARIANTS + db_printf("Queue type: %d\n", sq->sq_type); + if (sq->sq_lock) { + lock = &sq->sq_lock->mtx_object; + db_printf("Associated Interlock: %p - (%s) %s\n", lock, + LOCK_CLASS(lock)->lc_name, lock->lo_name); + } +#endif + db_printf("Blocked threads:\n"); + if (TAILQ_EMPTY(&sq->sq_blocked)) + db_printf("\tempty\n"); + else + TAILQ_FOREACH(td, &sq->sq_blocked, td_slpq) { + db_printf("\t%p (tid %d, pid %d, \"%s\")\n", td, + td->td_tid, td->td_proc->p_pid, + td->td_proc->p_comm); + } +} +#endif |
