Bug fix for spsc-queue test
[c11tester.git] / model.cc
index 136898e913808803972f63d5b7bcd67b1b945a5e..ea8f268ff270fa8d59674570103699c1eb36eb03 100644 (file)
--- a/model.cc
+++ b/model.cc
@@ -346,13 +346,13 @@ uint64_t ModelChecker::switch_to_master(ModelAction *act)
 
 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();
@@ -368,13 +368,13 @@ void ModelChecker::continueRunExecution(Thread *old)
 
 void ModelChecker::startRunExecution(ucontext_t *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();
@@ -406,7 +406,7 @@ Thread* ModelChecker::getNextThread()
                        scheduler->sleep(thr);
                }
 
-//             chooseThread(act, thr);
+       chooseThread(act, thr);
        }
        return nextThread;
 }
@@ -423,13 +423,24 @@ void ModelChecker::finishRunExecution(Thread *old)
 void ModelChecker::finishRunExecution(ucontext_t *old) 
 {
        scheduler->set_current_thread(NULL);
+       break_execution = true;
 }
 
 void ModelChecker::consumeAction()
 {
        ModelAction *curr = chosen_thread->get_pending();
-       chosen_thread->set_pending(NULL);
-       chosen_thread = execution->take_step(curr);
+       Thread * th = thread_current();
+       if (curr->get_type() == THREAD_FINISH && th != NULL)  {
+               // Thread finish must be consumed in the master context
+               scheduler->set_current_thread(NULL);
+               if (Thread::swap(th, &system_context) < 0) {
+                       perror("swap threads");
+                       exit(EXIT_FAILURE);
+               }
+       } else {
+               chosen_thread->set_pending(NULL);
+               chosen_thread = execution->take_step(curr);
+       }
 }
 
 void ModelChecker::chooseThread(ModelAction *act, Thread *thr)
@@ -477,12 +488,10 @@ uint64_t ModelChecker::switch_thread(ModelAction *act)
        if (old->is_waiting_on(old))
                assert_bug("Deadlock detected (thread %u)", curr_thread_num);
 
-       ModelAction *act2 = old->get_pending();
-               
-       if (act2 && execution->is_enabled(old) && !execution->check_action_enabled(act2)) {
+       if (act && execution->is_enabled(old) && !execution->check_action_enabled(act)) {
                scheduler->sleep(old);
        }
-//     chooseThread(act2, old);
+       chooseThread(act, old);
 
        curr_thread_num++;
        Thread* next = getNextThread();
@@ -536,13 +545,17 @@ void ModelChecker::handleChosenThread(Thread *old)
 
 void ModelChecker::handleChosenThread(ucontext_t *old)
 {
-       if (execution->has_asserted())
+       if (execution->has_asserted()) {
                finishRunExecution(old);
+               return;
+       }
        if (!chosen_thread)
                chosen_thread = get_next_thread();
-       if (!chosen_thread || chosen_thread->is_model_thread())
+       if (!chosen_thread || chosen_thread->is_model_thread()) {
                finishRunExecution(old);
-/*     if (chosen_thread->just_woken_up()) {
+               return;
+       }
+       if (chosen_thread->just_woken_up()) {
                chosen_thread->set_wakeup_state(false);
                chosen_thread->set_pending(NULL);
                chosen_thread = NULL;
@@ -551,9 +564,7 @@ void ModelChecker::handleChosenThread(ucontext_t *old)
                        finishRunExecution(old);
                else
                        startRunExecution(old); 
-       } else*/
-
-       {
+       } else {
                /* Consume the next action for a Thread */
                consumeAction();
 
@@ -596,7 +607,11 @@ void ModelChecker::run()
        checkfree = params.checkthreshold;
        for(int exec = 0;exec < params.maxexecutions;exec++) {
                chosen_thread = init_thread;
+               break_execution = false;
                do {
+                       if (break_execution)
+                               break;
+
                        thread_chosen = false;
                        curr_thread_num = 1;
                        startRunExecution(&system_context);