X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=model.cc;h=a1204d0ab852352600edb95063476bd6f2976fa7;hb=c4f504bb8deb86c8e2b06cb8ddaec5d92ec17e9d;hp=170edc748b8e9fc72c815d73a4ef1c098713587c;hpb=a79c7564164ca346b46122e34d3639f88c895fe9;p=c11tester.git diff --git a/model.cc b/model.cc index 170edc74..a1204d0a 100644 --- a/model.cc +++ b/model.cc @@ -344,7 +344,27 @@ uint64_t ModelChecker::switch_to_master(ModelAction *act) return old->get_return_value(); } -void ModelChecker::continueExecution(Thread *old) +void ModelChecker::continueRunExecution(Thread *old) +{ + if (params.traceminsize != 0 && + execution->get_curr_seq_num() > checkfree) { + checkfree += params.checkthreshold; + execution->collectActions(); + } + thread_chosen = false; + curr_thread_num = 1; + Thread *thr = getNextThread(); + if (thr != nullptr) { + scheduler->set_current_thread(thr); + if (Thread::swap(old, thr) < 0) { + perror("swap threads"); + exit(EXIT_FAILURE); + } + } else + handleChosenThread(old); +} + +void ModelChecker::startRunExecution(ucontext_t *old) { if (params.traceminsize != 0 && execution->get_curr_seq_num() > checkfree) { @@ -366,13 +386,14 @@ void ModelChecker::continueExecution(Thread *old) Thread* ModelChecker::getNextThread() { - Thread *thr = nullptr; + Thread *nextThread = nullptr; for (unsigned int i = curr_thread_num; i < get_num_threads(); i++) { thread_id_t tid = int_to_id(i); - thr = get_thread(tid); + Thread *thr = get_thread(tid); if (!thr->is_complete() && !thr->get_pending()) { curr_thread_num = i; + nextThread = thr; break; } ModelAction *act = thr->get_pending(); @@ -383,10 +404,10 @@ Thread* ModelChecker::getNextThread() chooseThread(act, thr); } - return thr; + return nextThread; } -void ModelChecker::finishExecution(Thread *old) +void ModelChecker::finishRunExecution(Thread *old) { scheduler->set_current_thread(NULL); if (Thread::swap(old, &system_context) < 0) { @@ -395,6 +416,11 @@ void ModelChecker::finishExecution(Thread *old) } } +void ModelChecker::finishRunExecution(ucontext_t *old) +{ + scheduler->set_current_thread(NULL); +} + void ModelChecker::consumeAction() { ModelAction *curr = chosen_thread->get_pending(); @@ -477,31 +503,60 @@ void ModelChecker::handleNewValidThread(Thread *old, Thread *next) void ModelChecker::handleChosenThread(Thread *old) { if (execution->has_asserted()) - finishExecution(old); + finishRunExecution(old); if (!chosen_thread) chosen_thread = get_next_thread(); if (!chosen_thread || chosen_thread->is_model_thread()) - finishExecution(old); + finishRunExecution(old); if (chosen_thread->just_woken_up()) { chosen_thread->set_wakeup_state(false); chosen_thread->set_pending(NULL); chosen_thread = NULL; // Allow this thread to stash the next pending action if (should_terminate_execution()) - finishExecution(old); + finishRunExecution(old); else - continueExecution(old); + continueRunExecution(old); } else { /* Consume the next action for a Thread */ consumeAction(); if (should_terminate_execution()) - finishExecution(old); + finishRunExecution(old); else - continueExecution(old); + continueRunExecution(old); } } +void ModelChecker::handleChosenThread(ucontext_t *old) +{ + if (execution->has_asserted()) + finishRunExecution(old); + if (!chosen_thread) + chosen_thread = get_next_thread(); + if (!chosen_thread || chosen_thread->is_model_thread()) + finishRunExecution(old); + if (chosen_thread->just_woken_up()) { + chosen_thread->set_wakeup_state(false); + chosen_thread->set_pending(NULL); + chosen_thread = NULL; + // Allow this thread to stash the next pending action + if (should_terminate_execution()) + finishRunExecution(old); + else + startRunExecution(old); + } else { + /* Consume the next action for a Thread */ + consumeAction(); + + if (should_terminate_execution()) + finishRunExecution(old); + else + startRunExecution(old); + } +} + + static void runChecker() { model->run(); delete model; @@ -535,9 +590,7 @@ void ModelChecker::run() chosen_thread = init_thread; thread_chosen = false; curr_thread_num = 1; - thread_id_t tid = int_to_id(1); - Thread *thr = get_thread(tid); - switch_from_master(thr); + startRunExecution(&system_context); finish_execution((exec+1) < params.maxexecutions); //restore random number generator state after rollback setstate(random_state);