Date: Wed, 18 Jul 2012 15:16:07 +0000 From: gmiller@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r239546 - in soc2012/gmiller/locking-head: . lib/libwitness Message-ID: <20120718151607.EECE01065672@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: gmiller Date: Wed Jul 18 15:16:07 2012 New Revision: 239546 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=239546 Log: r239588@FreeBSD-dev: root | 2012-07-15 01:23:43 -0500 Implement pthread_lockorder_begin_np(), pthread_lockorder_next_np(), and pthread_lockorder_end_np() to obtain a lock order graph. Modified: soc2012/gmiller/locking-head/ (props changed) soc2012/gmiller/locking-head/lib/libwitness/graph.c Modified: soc2012/gmiller/locking-head/lib/libwitness/graph.c ============================================================================== --- soc2012/gmiller/locking-head/lib/libwitness/graph.c Wed Jul 18 12:41:09 2012 (r239545) +++ soc2012/gmiller/locking-head/lib/libwitness/graph.c Wed Jul 18 15:16:07 2012 (r239546) @@ -27,6 +27,15 @@ #include "witness.h" +struct lock_iter { + SLIST_ENTRY(lock_iter) iter_next; + void *lock; +}; + +struct _pthread_lockorder_private { + SLIST_HEAD(lock_iter_head, lock_iter) lock_iter_head; +}; + struct lock_info *root = NULL; static int @@ -79,3 +88,72 @@ return (0); } + +static void +add_graph(struct pthread_lockorder_np *iter_node, struct lock_info *graph_node) +{ + struct lock_iter *iter; + + if (graph_node != NULL) { + iter = malloc(sizeof(struct pthread_lockorder_np)); + iter->lock = graph_node->lock; + SLIST_INSERT_HEAD(&iter_node->_pvt->lock_iter_head, iter, + iter_next); + + add_graph(iter_node, graph_node->sibling); + add_graph(iter_node, graph_node->child); + } +} + +void +pthread_lockorder_begin_np(struct pthread_lockorder_np *node) +{ + /* + The lock isn't needed to prevent races, but it is needed to ensure + that any locks grabbed by malloc() don't get logged. + */ + pthread_mutex_lock(&witness_mtx); + + node->_pvt = malloc(sizeof(struct _pthread_lockorder_private)); + + add_graph(node, root); + + pthread_mutex_unlock(&witness_mtx); +} + +int +pthread_lockorder_next_np(struct pthread_lockorder_np *node) +{ + struct lock_iter *iter; + + iter = SLIST_FIRST(&node->_pvt->lock_iter_head); + if (iter != NULL) { + SLIST_REMOVE_HEAD(&node->_pvt->lock_iter_head, iter_next); + + node->lock = iter->lock; + + free(iter); + + return (1); + } else { + return (0); + } +} + +void +pthread_lockorder_end_np(struct pthread_lockorder_np *node) +{ + struct lock_iter *iter; + + if (node->_pvt != NULL) { + while (!SLIST_EMPTY(&node->_pvt->lock_iter_head)) { + iter = SLIST_FIRST(&node->_pvt->lock_iter_head); + SLIST_REMOVE_HEAD(&node->_pvt->lock_iter_head, + iter_next); + free(iter); + } + + free(node->_pvt); + node->_pvt = NULL; + } +}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120718151607.EECE01065672>