socsvn commit: r239546 - in soc2012/gmiller/locking-head: .
lib/libwitness
gmiller at FreeBSD.org
gmiller at FreeBSD.org
Wed Jul 18 15:16:10 UTC 2012
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 at 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;
+ }
+}
More information about the svn-soc-all
mailing list