threads: move circular wait check into Threads::is_waiting_on
authorBrian Norris <banorris@uci.edu>
Wed, 27 Mar 2013 20:03:43 +0000 (13:03 -0700)
committerBrian Norris <banorris@uci.edu>
Wed, 27 Mar 2013 20:03:43 +0000 (13:03 -0700)
A Threads::is_waiting_on(Thread *) interface  provides a more generic
interface, which can be useful for tasks other than just circular wait
deadlock detection.

model.cc
model.h
threads-model.h
threads.cc

index 7df70eebbe271c88486a4c85e4289217f1a40e4b..879f1dea17d162b38ca240e4c628043ed00001c3 100644 (file)
--- a/model.cc
+++ b/model.cc
@@ -409,22 +409,6 @@ bool ModelChecker::is_deadlocked() const
        return blocking_threads;
 }
 
-/**
- * Check if a Thread has entered a circular wait deadlock situation. This will
- * not check other threads for potential deadlock situations, and may miss
- * deadlocks involving WAIT.
- *
- * @param t The thread which may have entered a deadlock
- * @return True if this Thread entered a deadlock; false otherwise
- */
-bool ModelChecker::is_circular_wait(const Thread *t) const
-{
-       for (Thread *waiting = t->waiting_on() ; waiting != NULL; waiting = waiting->waiting_on())
-               if (waiting == t)
-                       return true;
-       return false;
-}
-
 /**
  * Check if this is a complete execution. That is, have all thread completed
  * execution (rather than exiting because sleep sets have forced a redundant
@@ -3169,7 +3153,7 @@ void ModelChecker::run()
                                Thread *thr = get_thread(tid);
                                if (!thr->is_model_thread() && !thr->is_complete() && !thr->get_pending()) {
                                        switch_from_master(thr);
-                                       if (is_circular_wait(thr))
+                                       if (thr->is_waiting_on(thr))
                                                assert_bug("Deadlock detected");
                                }
                        }
diff --git a/model.h b/model.h
index 355764b7c4d290cfb3de64f7f0c0086a0ba83c73..6809612a9a996ee9072ce32e30f4df5982d5163d 100644 (file)
--- a/model.h
+++ b/model.h
@@ -282,7 +282,6 @@ private:
        bool is_feasible_prefix_ignore_relseq() const;
        bool is_infeasible() const;
        bool is_deadlocked() const;
-       bool is_circular_wait(const Thread *t) const;
        bool is_complete_execution() const;
        bool have_bug_reports() const;
        void print_bugs() const;
index eb0fd438d388931ef0316231abd828d6e5295581..eed11cbb0ce827bc4f3eea1ca5ba515ca36df874 100644 (file)
@@ -105,6 +105,7 @@ public:
        void set_pending(ModelAction *act) { pending = act; }
 
        Thread * waiting_on() const;
+       bool is_waiting_on(const Thread *t) const;
 
        /**
         * Remove one ModelAction from the waiting list
index 00e5c2fbd4a0f1287ac6b68b8be50a1a49b82bd8..e4b46561a0e7be13016661a541f09146b9726f28 100644 (file)
@@ -199,7 +199,7 @@ void Thread::set_state(thread_state s)
 }
 
 /**
- * Get the Thread that this Thread is waiting on
+ * Get the Thread that this Thread is immediately waiting on
  * @return The thread we are waiting on, if any; otherwise NULL
  */
 Thread * Thread::waiting_on() const
@@ -213,3 +213,19 @@ Thread * Thread::waiting_on() const
                return (Thread *)pending->get_mutex()->get_state()->locked;
        return NULL;
 }
+
+/**
+ * Check if this Thread is waiting (blocking) on a given Thread, directly or
+ * indirectly (via a chain of waiting threads)
+ *
+ * @param t The Thread on which we may be waiting
+ * @return True if we are waiting on Thread t; false otherwise
+ */
+bool Thread::is_waiting_on(const Thread *t) const
+{
+       Thread *wait;
+       for (wait = waiting_on(); wait != NULL; wait = wait->waiting_on())
+               if (wait == t)
+                       return true;
+       return false;
+}