X-Git-Url: http://plrg.eecs.uci.edu/git/?p=model-checker.git;a=blobdiff_plain;f=scanalysis.cc;h=d4102fe8b6a20148ff30ae5a83cdaf506f2753df;hp=daf41f8a19ba4395d61dff065f71422a422547dc;hb=d28d1a3b7aafbcd2caf80de26721293126830fa8;hpb=ecca9a3bfcfe77f1e6b53ff8cd57449f048bb629 diff --git a/scanalysis.cc b/scanalysis.cc index daf41f8..d4102fe 100644 --- a/scanalysis.cc +++ b/scanalysis.cc @@ -6,7 +6,9 @@ SCAnalysis::SCAnalysis(const ModelExecution *execution) : cvmap(), - cycleset(), + cyclic(false), + badrfset(), + lastwrmap(), threadlists(1), execution(execution) { @@ -16,18 +18,20 @@ SCAnalysis::~SCAnalysis() { } void SCAnalysis::print_list(action_list_t *list) { - action_list_t::iterator it; - model_print("---------------------------------------------------------------------\n"); - + if (cyclic) + model_print("Not SC\n"); unsigned int hash = 0; - for (it = list->begin(); it != list->end(); it++) { + for (action_list_t::iterator it = list->begin(); it != list->end(); it++) { const ModelAction *act = *it; if (act->get_seq_number() > 0) { - if (cycleset.contains(act)) - model_print("CYC"); + if (badrfset.contains(act)) + model_print("BRF "); act->print(); + if (badrfset.contains(act)) { + model_print("Desired Rf: %u \n",badrfset.get(act)->get_seq_number()); + } } hash = hash ^ (hash << 3) ^ ((*it)->hash()); } @@ -39,24 +43,44 @@ void SCAnalysis::analyze(action_list_t *actions) { buildVectors(actions); computeCV(actions); action_list_t *list = generateSC(actions); + check_rf(list); print_list(list); } -bool SCAnalysis::merge(ClockVector *cv, const ModelAction *act, ClockVector *cv2) { +void SCAnalysis::check_rf(action_list_t *list) { + for (action_list_t::iterator it = list->begin(); it != list->end(); it++) { + const ModelAction *act = *it; + if (act->is_read()) { + if (act->get_reads_from()!=lastwrmap.get(act->get_location())) + badrfset.put(act,lastwrmap.get(act->get_location())); + } + if (act->is_write()) + lastwrmap.put(act->get_location(), act); + } +} + +bool SCAnalysis::merge(ClockVector *cv, const ModelAction *act, const ModelAction *act2) { + ClockVector * cv2=cvmap.get(act2); + if (cv2==NULL) + return true; if (cv2->getClock(act->get_tid()) >= act->get_seq_number() && act->get_seq_number() != 0) { - cycleset.put(act, act); + cyclic=true; + //refuse to introduce cycles into clock vectors + return false; } + return cv->merge(cv2); } ModelAction * SCAnalysis::getNextAction() { ModelAction *act = NULL; + /* Find the earliest in SC ordering */ for (int i = 0; i <= maxthreads; i++) { action_list_t *threadlist = &threadlists[i]; if (threadlist->empty()) continue; ModelAction *first = threadlist->front(); - if (act == NULL) { + if (act==NULL) { act = first; continue; } @@ -67,29 +91,45 @@ ModelAction * SCAnalysis::getNextAction() { } if (act == NULL) return act; - //print cycles in a nice way to avoid confusion - //make sure thread starts appear after the create - if (act->is_thread_start()) { - ModelAction *createact = execution->get_thread(act)->get_creation(); - if (createact) { - action_list_t *threadlist = &threadlists[id_to_int(createact->get_tid())]; - if (!threadlist->empty()) { - ModelAction *first = threadlist->front(); - if (first->get_seq_number() <= createact->get_seq_number()) - act = first; + + /* Find the model action with the earliest sequence number in case of a cycle. + */ + + for (int i = 0; i <= maxthreads; i++) { + action_list_t *threadlist = &threadlists[i]; + if (threadlist->empty()) + continue; + ModelAction *first = threadlist->front(); + ClockVector *cvfirst = cvmap.get(first); + if (first->get_seq_number()get_seq_number()) { + bool candidate=true; + for (int j = 0; j <= maxthreads; j++) { + action_list_t *threadlist2 = &threadlists[j]; + if (threadlist2->empty()) + continue; + ModelAction *check = threadlist2->front(); + if ((check!=first) && + cvfirst->synchronized_since(check)) { + candidate=false; + break; + } } + if (candidate) + act=first; } } - //make sure that joins appear after the thread is finished - if (act->is_thread_join()) { - int jointhread = id_to_int(act->get_thread_operand()->get_id()); - action_list_t *threadlist = &threadlists[jointhread]; - if (!threadlist->empty()) { - act = threadlist->front(); + /* See if hb demands an earlier action. */ + for (int i = 0; i <= maxthreads; i++) { + action_list_t *threadlist = &threadlists[i]; + if (threadlist->empty()) + continue; + ModelAction *first = threadlist->front(); + ClockVector *cv = act->get_cv(); + if (cv->synchronized_since(first)) { + act = first; } } - return act; } @@ -105,7 +145,10 @@ action_list_t * SCAnalysis::generateSC(action_list_t *list) { //add ordering constraints from this choice if (updateConstraints(act)) { //propagate changes if we have them + bool oc=cyclic; computeCV(list); + if (!oc && cyclic) + model_print("XXXXXXXXXXXXXX\n"); } //add action to end sclist->push_back(act); @@ -128,7 +171,6 @@ void SCAnalysis::buildVectors(action_list_t *list) { bool SCAnalysis::updateConstraints(ModelAction *act) { bool changed = false; - ClockVector *actcv = cvmap.get(act); for (int i = 0; i <= maxthreads; i++) { thread_id_t tid = int_to_id(i); if (tid == act->get_tid()) @@ -144,7 +186,7 @@ bool SCAnalysis::updateConstraints(ModelAction *act) { break; if (write->get_location() == act->get_location()) { //write is sc after act - merge(writecv, write, actcv); + merge(writecv, write, act); changed = true; break; } @@ -159,7 +201,7 @@ bool SCAnalysis::processRead(ModelAction *read, ClockVector *cv) { /* Merge in the clock vector from the write */ const ModelAction *write = read->get_reads_from(); ClockVector *writecv = cvmap.get(write); - changed |= writecv == NULL || (merge(cv, read, writecv) && (*read < *write)); + changed |= merge(cv, read, write) && (*read < *write); for (int i = 0; i <= maxthreads; i++) { thread_id_t tid = int_to_id(i); @@ -183,7 +225,7 @@ bool SCAnalysis::processRead(ModelAction *read, ClockVector *cv) { write -rf-> R => R -sc-> write2 */ if (write2cv->synchronized_since(write)) { - changed |= merge(write2cv, write2, cv); + changed |= merge(write2cv, write2, read); } //looking for earliest write2 in iteration to satisfy this @@ -191,7 +233,7 @@ bool SCAnalysis::processRead(ModelAction *read, ClockVector *cv) { write -rf-> R => write2 -sc-> write */ if (cv->synchronized_since(write2)) { - changed |= writecv == NULL || merge(writecv, write, write2cv); + changed |= writecv==NULL || merge(writecv, write, write2); break; } } @@ -212,20 +254,19 @@ void SCAnalysis::computeCV(action_list_t *list) { ModelAction *lastact = last_act[id_to_int(act->get_tid())]; if (act->is_thread_start()) lastact = execution->get_thread(act)->get_creation(); - ClockVector *lastcv = (lastact != NULL) ? cvmap.get(lastact) : NULL; last_act[id_to_int(act->get_tid())] = act; ClockVector *cv = cvmap.get(act); if (cv == NULL) { - cv = new ClockVector(lastcv, act); + cv = new ClockVector(NULL, act); cvmap.put(act, cv); - } else if (lastcv != NULL) { - merge(cv, act, lastcv); + } + if (lastact != NULL) { + merge(cv, act, lastact); } if (act->is_thread_join()) { Thread *joinedthr = act->get_thread_operand(); ModelAction *finish = execution->get_last_action(joinedthr->get_id()); - ClockVector *finishcv = cvmap.get(finish); - changed |= (finishcv == NULL) || merge(cv, act, finishcv); + changed |= merge(cv, act, finish); } if (act->is_read()) { changed |= processRead(act, cv);