X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=model.cc;h=856a33d2cdfa13d2db741797d4fc0f1681a9fd04;hb=09c3eb5539455e82dcb357fbce82bf5974c3a37c;hp=c832b03710fc360ab17bcb5b3afe7a5920c1cfa6;hpb=3e520de48b5be0b0d4fa4a5f033e207b17c4496d;p=model-checker.git diff --git a/model.cc b/model.cc index c832b03..856a33d 100644 --- a/model.cc +++ b/model.cc @@ -159,6 +159,14 @@ void ModelChecker::reset_to_initial_state() /* Print all model-checker output before rollback */ fflush(model_out); + /** + * FIXME: if we utilize partial rollback, we will need to free only + * those pending actions which were NOT pending before the rollback + * point + */ + for (unsigned int i = 0; i < get_num_threads(); i++) + delete get_thread(int_to_id(i))->get_pending(); + snapshot_backtrack_before(0); } @@ -293,9 +301,7 @@ void ModelChecker::execute_sleep_set() for (unsigned int i = 0; i < get_num_threads(); i++) { thread_id_t tid = int_to_id(i); Thread *thr = get_thread(tid); - if (scheduler->is_sleep_set(thr) && thr->get_pending() == NULL) { - scheduler->next_thread(thr); - Thread::swap(&system_context, thr); + if (scheduler->is_sleep_set(thr) && thr->get_pending()) { thr->get_pending()->set_sleep_flag(); } } @@ -321,11 +327,22 @@ void ModelChecker::set_bad_synchronization() priv->bad_synchronization = true; } +/** + * Check whether the current trace has triggered an assertion which should halt + * its execution. + * + * @return True, if the execution should be aborted; false otherwise + */ bool ModelChecker::has_asserted() const { return priv->asserted; } +/** + * Trigger a trace assertion which should cause this execution to be halted. + * This can be due to a detected bug or due to an infeasibility that should + * halt ASAP. + */ void ModelChecker::set_assert() { priv->asserted = true; @@ -2665,6 +2682,7 @@ uint64_t ModelChecker::switch_to_master(ModelAction *act) { DBG(); Thread *old = thread_current(); + ASSERT(!old->get_pending()); old->set_pending(act); if (Thread::swap(old, &system_context) < 0) { perror("swap threads"); @@ -2681,9 +2699,6 @@ uint64_t ModelChecker::switch_to_master(ModelAction *act) */ Thread * ModelChecker::take_step(ModelAction *curr) { - if (has_asserted()) - return NULL; - Thread *curr_thrd = get_thread(curr); ASSERT(curr_thrd->get_state() == THREAD_READY); @@ -2751,8 +2766,25 @@ void ModelChecker::run() add_thread(t); do { - scheduler->next_thread(t); - Thread::swap(&system_context, t); + /* + * Stash next pending action(s) for thread(s). There + * should only need to stash one thread's action--the + * thread which just took a step--plus the first step + * for any newly-created thread + */ + for (unsigned int i = 0; i < get_num_threads(); i++) { + thread_id_t tid = int_to_id(i); + Thread *thr = get_thread(tid); + if (!thr->is_model_thread() && !thr->is_complete() && !thr->get_pending()) { + scheduler->next_thread(thr); + Thread::swap(&system_context, thr); + } + } + + /* Catch assertions from prior take_step or from + * between-ModelAction bugs (e.g., data races) */ + if (has_asserted()) + break; /* Consume the next action for a Thread */ ModelAction *curr = t->get_pending();