X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=model.cc;h=94620ea9d0400fcee239973705361210542040f5;hb=dd56df466206a5f34f1d9b1777d1f076f7c33e0f;hp=b29df05cafe86fadefa27b85c535e30eb94fd43e;hpb=17b667f2d53729212d23e62a3f9464b8180e01f6;p=model-checker.git diff --git a/model.cc b/model.cc index b29df05..94620ea 100644 --- a/model.cc +++ b/model.cc @@ -101,7 +101,7 @@ thread_id_t ModelChecker::get_next_id() } /** @return the number of user threads created during this execution */ -unsigned int ModelChecker::get_num_threads() +unsigned int ModelChecker::get_num_threads() const { return priv->next_thread_id; } @@ -244,6 +244,26 @@ void ModelChecker::wake_up_sleeping_actions(ModelAction * curr) { } } +/** + * Check if we are in a deadlock. Should only be called at the end of an + * execution, although it should not give false positives in the middle of an + * execution (there should be some ENABLED thread). + * + * @return True if program is in a deadlock; false otherwise + */ +bool ModelChecker::is_deadlocked() const +{ + bool blocking_threads = false; + for (unsigned int i = 0; i < get_num_threads(); i++) { + Thread *t = get_thread(int_to_id(i)); + if (scheduler->is_enabled(t) != THREAD_DISABLED) + return false; + else if (!t->is_model_thread() && t->get_pending()) + blocking_threads = true; + } + return blocking_threads; +} + /** * Queries the model-checker for more executions to explore and, if one * exists, resets the model-checker state to execute a new execution. @@ -257,6 +277,8 @@ bool ModelChecker::next_execution() num_executions++; + if (is_deadlocked()) + printf("ERROR: DEADLOCK\n"); if (isfinalfeasible()) { printf("Earliest divergence point since last feasible execution:\n"); if (earliest_diverge)