Skip site navigation (1)Skip section navigation (2)
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>