X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=model.cc;h=84b296e56b109e2a4295d312c1a7746a5267d30c;hb=75170f48eddae922e7fbdac00fc949f00c8cb36e;hp=f50b0f9a60777557429c33ab7fc4b3236ef1cb6f;hpb=fe8423ca853f5d614e618fe49d37d0943d416809;p=c11tester.git diff --git a/model.cc b/model.cc index f50b0f9a..84b296e5 100644 --- a/model.cc +++ b/model.cc @@ -4,12 +4,14 @@ #include "schedule.h" #include "common.h" +#define INITIAL_THREAD_ID 0 + ModelChecker *model; ModelChecker::ModelChecker() { - /* First thread created (system_thread) will have id 1 */ - this->used_thread_id = 0; + /* First thread created will have id (INITIAL_THREAD_ID + 1) */ + this->used_thread_id = INITIAL_THREAD_ID; /* Initialize default scheduler */ this->scheduler = new Scheduler(); @@ -30,14 +32,24 @@ ModelChecker::~ModelChecker() delete rootNode; } -int ModelChecker::get_next_id() +void ModelChecker::reset_to_initial_state() { - return ++used_thread_id; + DEBUG("+++ Resetting to initial state +++\n"); + std::map::iterator it; + for (it = thread_map.begin(); it != thread_map.end(); it++) { + delete (*it).second; + } + thread_map.clear(); + action_trace = new action_list_t(); + currentNode = rootNode; + current_action = NULL; + used_thread_id = INITIAL_THREAD_ID; + /* scheduler reset ? */ } -void ModelChecker::add_system_thread(Thread *t) +int ModelChecker::get_next_id() { - this->system_thread = t; + return ++used_thread_id; } Thread * ModelChecker::schedule_next_thread() @@ -97,6 +109,7 @@ thread_id_t ModelChecker::advance_backtracking_state() bool ModelChecker::next_execution() { num_executions++; + print_summary(); if ((exploring = model->get_next_backtrack()) == NULL) return false; model->reset_to_initial_state(); @@ -106,9 +119,7 @@ bool ModelChecker::next_execution() ModelAction * ModelChecker::get_last_conflict(ModelAction *act) { - void *loc = act->get_location(); action_type type = act->get_type(); - thread_id_t id = act->get_tid(); switch (type) { case THREAD_CREATE: @@ -124,14 +135,8 @@ ModelAction * ModelChecker::get_last_conflict(ModelAction *act) action_list_t::reverse_iterator rit; for (rit = action_trace->rbegin(); rit != action_trace->rend(); rit++) { ModelAction *prev = *rit; - if (prev->get_location() != loc) - continue; - if (type == ATOMIC_READ && prev->get_type() != ATOMIC_WRITE) - continue; - /* Conflict from the same thread is not really a conflict */ - if (id == prev->get_tid()) - return NULL; - return prev; + if (act->is_dependent(prev)) + return prev; } return NULL; } @@ -154,15 +159,27 @@ void ModelChecker::set_backtracking(ModelAction *act) if (node->setBacktrack(act->get_tid()) != 0) return; - printf("Setting backtrack: conflict = %d, instead tid = %d\n", + DEBUG("Setting backtrack: conflict = %d, instead tid = %d\n", prev->get_tid(), act->get_tid()); - prev->print(); - act->print(); + if (DBG_ENABLED()) { + prev->print(); + act->print(); + } Backtrack *back = new Backtrack(prev, action_trace); backtrack_list.push_back(back); } +Backtrack * ModelChecker::get_next_backtrack() +{ + Backtrack *next; + if (backtrack_list.empty()) + return NULL; + next = backtrack_list.back(); + backtrack_list.pop_back(); + return next; +} + void ModelChecker::check_current_action(void) { ModelAction *next = this->current_action; @@ -171,6 +188,7 @@ void ModelChecker::check_current_action(void) DEBUG("trying to push NULL action...\n"); return; } + current_action = NULL; nextThread = advance_backtracking_state(); next->set_node(currentNode); set_backtracking(next); @@ -178,7 +196,7 @@ void ModelChecker::check_current_action(void) this->action_trace->push_back(next); } -void ModelChecker::print_trace(void) +void ModelChecker::print_summary(void) { action_list_t::iterator it; @@ -189,7 +207,7 @@ void ModelChecker::print_trace(void) scheduler->print(); - printf("\nTrace:\n\n"); + printf("Trace:\n\n"); for (it = action_trace->begin(); it != action_trace->end(); it++) { DBG(); @@ -205,16 +223,20 @@ int ModelChecker::add_thread(Thread *t) return 0; } +void ModelChecker::remove_thread(Thread *t) +{ + scheduler->remove_thread(t); +} + int ModelChecker::switch_to_master(ModelAction *act) { - Thread *old, *next; + Thread *old; DBG(); old = thread_current(); set_current_action(act); old->set_state(THREAD_READY); - next = system_thread; - return old->swap(next); + return Thread::swap(old, get_system_context()); } ModelAction::ModelAction(action_type_t type, memory_order order, void *loc, int value) @@ -229,6 +251,62 @@ ModelAction::ModelAction(action_type_t type, memory_order order, void *loc, int act->value = value; } +bool ModelAction::is_read() +{ + return type == ATOMIC_READ; +} + +bool ModelAction::is_write() +{ + return type == ATOMIC_WRITE; +} + +bool ModelAction::is_acquire() +{ + switch (order) { + case memory_order_acquire: + case memory_order_acq_rel: + case memory_order_seq_cst: + return true; + default: + return false; + } +} + +bool ModelAction::is_release() +{ + switch (order) { + case memory_order_release: + case memory_order_acq_rel: + case memory_order_seq_cst: + return true; + default: + return false; + } +} + +bool ModelAction::same_var(ModelAction *act) +{ + return location == act->location; +} + +bool ModelAction::same_thread(ModelAction *act) +{ + return tid == act->tid; +} + +bool ModelAction::is_dependent(ModelAction *act) +{ + if (!is_read() && !is_write()) + return false; + if (!act->is_read() && !act->is_write()) + return false; + if (same_var(act) && !same_thread(act) && + (is_write() || act->is_write())) + return true; + return false; +} + void ModelAction::print(void) { const char *type_str;