X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=scanalysis.cc;h=ff7854a87e8a31aec8e3ae105d403ad0b3559c66;hb=383429e233bec211bb45b00ed3c1e0fb18ee7673;hp=6391e58aac3f7fd0a44685fc305b9abd2c4a700b;hpb=38cb7400c16ad0a04355ec77af2bf5da2dbfaad5;p=model-checker.git diff --git a/scanalysis.cc b/scanalysis.cc index 6391e58..ff7854a 100644 --- a/scanalysis.cc +++ b/scanalysis.cc @@ -5,11 +5,13 @@ SCAnalysis::SCAnalysis() { cvmap=new HashTable(); + cycleset=new HashTable(); threadlists=new SnapVector(1); } SCAnalysis::~SCAnalysis() { delete cvmap; + delete cycleset; delete threadlists; } @@ -22,8 +24,11 @@ void SCAnalysis::print_list(action_list_t *list) { for (it = list->begin(); it != list->end(); it++) { const ModelAction *act = *it; - if (act->get_seq_number() > 0) + if (act->get_seq_number() > 0) { + if (cycleset->contains(act)) + model_print("CYC"); act->print(); + } hash = hash^(hash<<3)^((*it)->hash()); } model_print("HASH %u\n", hash); @@ -37,6 +42,13 @@ void SCAnalysis::analyze(action_list_t * actions) { print_list(list); } +bool SCAnalysis::merge(ClockVector * cv, const ModelAction * act, ClockVector *cv2) { + if (cv2->getClock(act->get_tid())>=act->get_seq_number() && act->get_seq_number() != 0) { + cycleset->put(act, act); + } + return cv->merge(cv2); +} + ModelAction * SCAnalysis::getNextAction() { ModelAction *act=NULL; for(int i=0;i<=maxthreads;i++) { @@ -53,10 +65,35 @@ ModelAction * SCAnalysis::getNextAction() { act=first; } } + 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=model->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; + } + } + } + + //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(); + } + } + return act; } -action_list_t * SCAnalysis::generateSC(action_list_t *list) { +action_list_t * SCAnalysis::generateSC(action_list_t *list) { action_list_t *sclist=new action_list_t(); while (true) { ModelAction * act=getNextAction(); @@ -107,11 +144,11 @@ bool SCAnalysis::updateConstraints(ModelAction *act) { break; if (write->get_location() == act->get_location()) { //write is sc after act - writecv->merge(actcv); + merge(writecv, write, actcv); changed=true; break; } - } + } } return changed; } @@ -122,7 +159,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 || cv->merge(writecv) && (*read < *write)); + changed |= writecv == NULL || (merge(cv, read, writecv) && (*read < *write)); for(int i=0;i<=maxthreads;i++) { thread_id_t tid=int_to_id(i); @@ -141,20 +178,20 @@ bool SCAnalysis::processRead(ModelAction *read, ClockVector *cv) { ClockVector *write2cv = cvmap->get(write2); if (write2cv == NULL) continue; - + /* write -sc-> write2 && write -rf-> R => R -sc-> write2 */ if (write2cv->synchronized_since(write)) { - changed |= write2cv->merge(cv); + changed |= merge(write2cv, write2, cv); } - + //looking for earliest write2 in iteration to satisfy this /* write2 -sc-> R && write -rf-> R => write2 -sc-> write */ if (cv->synchronized_since(write2)) { - changed |= writecv == NULL || writecv->merge(write2cv); + changed |= writecv == NULL || merge(writecv, write, write2cv); break; } } @@ -183,13 +220,13 @@ void SCAnalysis::computeCV(action_list_t *list) { cv = new ClockVector(lastcv, act); cvmap->put(act, cv); } else if ( lastcv != NULL ) { - cv->merge(lastcv); + merge(cv, act, lastcv); } if (act->is_thread_join()) { Thread *joinedthr = act->get_thread_operand(); ModelAction *finish = model->get_last_action(joinedthr->get_id()); ClockVector *finishcv = cvmap->get(finish); - changed |= (finishcv == NULL) || cv->merge(finishcv); + changed |= (finishcv == NULL) || merge(cv, act, finishcv); } if (act->is_read()) { changed|=processRead(act, cv);