--- //depot/vendor/freebsd/src/sys/kern/kern_mutex.c 2005/10/18 18:30:35 +++ //depot/projects/smpng/sys/kern/kern_mutex.c 2005/12/08 22:23:18 @@ -89,16 +94,26 @@ #define mtx_owner(m) (mtx_unowned((m)) ? NULL \ : (struct thread *)((m)->mtx_lock & MTX_FLAGMASK)) +#ifdef DDB +static void db_show_mtx(struct lock_object *lock); +#endif + /* * Lock classes for sleep and spin mutexes. */ struct lock_class lock_class_mtx_sleep = { "sleep mutex", - LC_SLEEPLOCK | LC_RECURSABLE + LC_SLEEPLOCK | LC_RECURSABLE, +#ifdef DDB + db_show_mtx +#endif }; struct lock_class lock_class_mtx_spin = { "spin mutex", - LC_SPINLOCK | LC_RECURSABLE + LC_SPINLOCK | LC_RECURSABLE, +#ifdef DDB + db_show_mtx +#endif }; /* @@ -905,3 +950,56 @@ mtx_init(&devmtx, "cdev", NULL, MTX_DEF); mtx_lock(&Giant); } + +#ifdef DDB +/* XXX: This function is not mutex-specific. */ +DB_SHOW_COMMAND(lock, db_show_lock) +{ + struct lock_object *lock; + + if (!have_addr) + return; + lock = (struct lock_object *)addr; + if (lock->lo_class != &lock_class_mtx_sleep && + lock->lo_class != &lock_class_mtx_spin && + lock->lo_class != &lock_class_sx) { + db_printf("Unknown lock class\n"); + return; + } + db_printf(" class: %s\n", lock->lo_class->lc_name); + db_printf(" name: %s\n", lock->lo_name); + if (lock->lo_type && lock->lo_type != lock->lo_name) + db_printf(" type: %s\n", lock->lo_type); + lock->lo_class->lc_ddb_show(lock); +} + +void +db_show_mtx(struct lock_object *lock) +{ + struct thread *td; + struct mtx *m; + + m = (struct mtx *)lock; + + db_printf(" flags: {"); + if (m->mtx_object.lo_class == &lock_class_mtx_spin) + db_printf("SPIN"); + else + db_printf("DEF"); + if (m->mtx_object.lo_flags & LO_RECURSABLE) + db_printf(", RECURSE"); + if (m->mtx_object.lo_flags & LO_DUPOK) + db_printf(", DUPOK"); + db_printf("}\n"); + db_printf(" owner: "); + if (mtx_unowned(m)) + db_printf("UNOWNED\n"); + else { + td = mtx_owner(m); + db_printf("%p (tid %d, pid %d, \"%s\")\n", td, td->td_tid, + td->td_proc->p_pid, td->td_proc->p_comm); + if (mtx_recursed(m)) + db_printf(" recursed: %d\n", m->mtx_recurse); + } +} +#endif --- //depot/vendor/freebsd/src/sys/kern/kern_sx.c 2005/01/06 23:37:37 +++ //depot/projects/smpng/sys/kern/kern_sx.c 2005/12/08 22:23:18 @@ -36,17 +36,30 @@ #include __FBSDID("$FreeBSD: src/sys/kern/kern_sx.c,v 1.25 2005/01/06 23:35:39 imp Exp $"); +#include "opt_ddb.h" + #include #include #include +#include #include #include #include +#include #include +#include + +#ifdef DDB +static void db_show_sx(struct lock_object *lock); +#endif + struct lock_class lock_class_sx = { "sx", - LC_SLEEPLOCK | LC_SLEEPABLE | LC_RECURSABLE | LC_UPGRADABLE + LC_SLEEPLOCK | LC_SLEEPABLE | LC_RECURSABLE | LC_UPGRADABLE, +#ifdef DDB + db_show_sx +#endif }; #ifndef INVARIANTS @@ -367,3 +380,26 @@ } } #endif /* INVARIANT_SUPPORT */ + +#ifdef DDB +void +db_show_sx(struct lock_object *lock) +{ + struct thread *td; + struct sx *sx; + + sx = (struct sx *)lock; + + db_printf(" locked: "); + if (sx->sx_cnt < 0) { + td = sx->sx_xholder; + db_printf(" XLOCK: %p (tid %d, pid %d, \"%s\")\n", td, + td->td_tid, td->td_proc->p_pid, td->td_proc->p_comm); + } else if (sx->sx_cnt > 0) + db_printf(" SLOCK: %d locks\n", sx->sx_cnt); + else + db_printf(" UNLOCKED\n"); + db_printf(" waiters: %d shared, %d exclusive\n", sx->sx_shrd_wcnt, + sx->sx_excl_wcnt); +} +#endif --- //depot/vendor/freebsd/src/sys/sys/lock.h 2005/12/05 22:03:48 +++ //depot/projects/smpng/sys/sys/lock.h 2005/12/08 22:23:18 @@ -50,6 +50,7 @@ struct lock_class { const char *lc_name; u_int lc_flags; + void (*lc_ddb_show)(struct lock_object *lock); }; #define LC_SLEEPLOCK 0x00000001 /* Sleep lock. */