From: Brian Norris Date: Wed, 27 Mar 2013 20:03:43 +0000 (-0700) Subject: threads: move circular wait check into Threads::is_waiting_on X-Git-Tag: oopsla2013~120 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=a11b6cce3a692a041cbfb772282a68be7949eb02;p=model-checker.git threads: move circular wait check into Threads::is_waiting_on 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. --- diff --git a/model.cc b/model.cc index 7df70ee..879f1de 100644 --- 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 355764b..6809612 100644 --- 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; diff --git a/threads-model.h b/threads-model.h index eb0fd43..eed11cb 100644 --- a/threads-model.h +++ b/threads-model.h @@ -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 diff --git a/threads.cc b/threads.cc index 00e5c2f..e4b4656 100644 --- a/threads.cc +++ b/threads.cc @@ -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; +}