summaryrefslogtreecommitdiff
path: root/sys/kern/subr_sleepqueue.c
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2006-01-27 22:24:07 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2006-01-27 22:24:07 +0000
commitf126e754e00e67f9fb6bbff1542fa2062e8d2ab9 (patch)
tree9f7260b793fc191d364e74dae4d8fa68b0221adc /sys/kern/subr_sleepqueue.c
parent6966c3348250222dd3b3930f240e3d257f099f13 (diff)
Notes
Diffstat (limited to 'sys/kern/subr_sleepqueue.c')
-rw-r--r--sys/kern/subr_sleepqueue.c66
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