X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=model.cc;h=88b3302acd5804a2a0756e818e5e9fc98092e0de;hb=57748ff26d916528ba0df0b1d2c699a901386d5f;hp=f7c10f86053b9151988524062d0b34b1b5d255c6;hpb=ec7cf0eb61ee239b3da1f184a9e43f77b0dcc25d;p=c11tester.git diff --git a/model.cc b/model.cc index f7c10f86..88b3302a 100644 --- a/model.cc +++ b/model.cc @@ -33,14 +33,14 @@ ModelChecker::ModelChecker() : params(), restart_flag(false), scheduler(new Scheduler()), - execution(new ModelExecution(this, scheduler)), history(new ModelHistory()), + execution(new ModelExecution(this, scheduler)), execution_number(1), trace_analyses(), inspect_plugin(NULL) { memset(&stats,0,sizeof(struct execution_stats)); - init_thread = new Thread(execution->get_next_id(), (thrd_t *) model_malloc(sizeof(thrd_t)), &user_main_wrapper, NULL, NULL); // L: user_main_wrapper passes the user program + init_thread = new Thread(execution->get_next_id(), (thrd_t *) model_malloc(sizeof(thrd_t)), &user_main_wrapper, NULL, NULL); #ifdef TLS init_thread->setTLS((char *)get_tls_addr()); #endif @@ -130,7 +130,7 @@ Thread * ModelChecker::get_next_thread() * @param msg Descriptive message for the bug (do not include newline char) * @return True if bug is immediately-feasible */ -bool ModelChecker::assert_bug(const char *msg, ...) +void ModelChecker::assert_bug(const char *msg, ...) { char str[800]; @@ -139,7 +139,7 @@ bool ModelChecker::assert_bug(const char *msg, ...) vsnprintf(str, sizeof(str), msg, ap); va_end(ap); - return execution->assert_bug(str); + execution->assert_bug(str); } /** @@ -150,8 +150,8 @@ bool ModelChecker::assert_bug(const char *msg, ...) void ModelChecker::assert_user_bug(const char *msg) { /* If feasible bug, bail out now */ - if (assert_bug(msg)) - switch_to_master(NULL); + assert_bug(msg); + switch_to_master(NULL); } /** @brief Print bug report listing for this execution (if any bugs exist) */ @@ -163,7 +163,7 @@ void ModelChecker::print_bugs() const bugs->size(), bugs->size() > 1 ? "s" : ""); for (unsigned int i = 0;i < bugs->size();i++) - (*bugs)[i]->print(); + (*bugs)[i] -> print(); } /** @@ -174,16 +174,13 @@ void ModelChecker::print_bugs() const */ void ModelChecker::record_stats() { - stats.num_total++; - if (!execution->isfeasibleprefix()) - stats.num_infeasible++; - else if (execution->have_bug_reports()) - stats.num_buggy_executions++; + stats.num_total ++; + if (execution->have_bug_reports()) + stats.num_buggy_executions ++; else if (execution->is_complete_execution()) - stats.num_complete++; + stats.num_complete ++; else { - stats.num_redundant++; - + //All threads are sleeping /** * @todo We can violate this ASSERT() when fairness/sleep sets * conflict to cause an execution to terminate, e.g. with: @@ -197,9 +194,7 @@ void ModelChecker::record_stats() void ModelChecker::print_stats() const { model_print("Number of complete, bug-free executions: %d\n", stats.num_complete); - model_print("Number of redundant executions: %d\n", stats.num_redundant); model_print("Number of buggy executions: %d\n", stats.num_buggy_executions); - model_print("Number of infeasible executions: %d\n", stats.num_infeasible); model_print("Total executions: %d\n", stats.num_total); } @@ -238,8 +233,7 @@ bool ModelChecker::next_execution() { DBG(); /* Is this execution a feasible execution that's worth bug-checking? */ - bool complete = execution->isfeasibleprefix() && - (execution->is_complete_execution() || + bool complete = (execution->is_complete_execution() || execution->have_bug_reports()); /* End-of-execution bug checks */ @@ -262,15 +256,16 @@ bool ModelChecker::next_execution() return true; } // test code - execution_number++; + execution_number ++; reset_to_initial_state(); + history->set_new_exec_flag(); return false; } /** @brief Run trace analyses on complete trace */ void ModelChecker::run_trace_analyses() { - for (unsigned int i = 0;i < trace_analyses.size();i++) - trace_analyses[i]->analyze(execution->get_action_trace()); + for (unsigned int i = 0;i < trace_analyses.size();i ++) + trace_analyses[i] -> analyze(execution->get_action_trace()); } /** @@ -353,14 +348,13 @@ static void runChecker() { void ModelChecker::startChecker() { startExecution(get_system_context(), runChecker); + snapshot_stack_init(); + snapshot_record(0); } bool ModelChecker::should_terminate_execution() { - /* Infeasible -> don't take any more steps */ - if (execution->is_infeasible()) - return true; - else if (execution->isfeasibleprefix() && execution->have_fatal_bug_reports()) { + if (execution->have_bug_reports()) { execution->set_assert(); return true; } else if (execution->isFinished()) { @@ -390,20 +384,6 @@ void ModelChecker::startMainThread() { main_thread_startup(); } -static bool is_nonsc_write(const ModelAction *act) { - if (act->get_type() == ATOMIC_WRITE) { - std::memory_order order = act->get_mo(); - switch(order) { - case std::memory_order_relaxed: - case std::memory_order_release: - return true; - default: - return false; - } - } - return false; -} - /** @brief Run ModelChecker for the user program */ void ModelChecker::run() { @@ -421,12 +401,11 @@ void ModelChecker::run() * thread which just took a step--plus the first step * for any newly-created thread */ - ModelAction * pending; 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() && ((!(pending=thr->get_pending())) || is_nonsc_write(pending)) ) { - switch_from_master(thr); // L: context swapped, and action type of thr changed. + if (!thr->is_model_thread() && !thr->is_complete() && !thr->get_pending()) { + switch_from_master(thr); if (thr->is_waiting_on(thr)) assert_bug("Deadlock detected (thread %u)", i); } @@ -471,6 +450,12 @@ void ModelChecker::run() t = get_next_thread(); if (!t || t->is_model_thread()) break; + if (t->just_woken_up()) { + t->set_wakeup_state(false); + t->set_pending(NULL); + t = NULL; + continue; // Allow this thread to stash the next pending action + } /* Consume the next action for a Thread */ ModelAction *curr = t->get_pending(); @@ -488,4 +473,9 @@ void ModelChecker::run() /* Have the trace analyses dump their output. */ for (unsigned int i = 0;i < trace_analyses.size();i++) trace_analyses[i]->finish(); + + /* unlink tmp file created by last child process */ + char filename[256]; + snprintf_(filename, sizeof(filename), "C11FuzzerTmp%d", getpid()); + unlink(filename); }