race->isnewwrite=isnewwrite;
race->address=address;
unrealizedraces.push_back(race);
- checkDataRaces();
+
+ /* If the race is realized, bail out now. */
+ if (checkDataRaces()) {
+ model->assert_thread();
+ }
}
/** This function goes through the list of unrealized data races,
* removes the impossible ones, and print the realized ones. */
-void checkDataRaces() {
- if (true) {
+bool checkDataRaces() {
+ if (model->isfeasibleprefix()) {
/* Prune the non-racing unrealized dataraces */
unsigned int i,newloc=0;
for(i=0;i<unrealizedraces.size();i++) {
}
if (newloc!=i)
unrealizedraces.resize(newloc);
- for(i=0;i<unrealizedraces.size();i++) {
- struct DataRace * race=unrealizedraces[i];
- printRace(race);
+
+ if (unrealizedraces.size()!=0) {
+ /* We have an actual realized race. */
+ for(i=0;i<unrealizedraces.size();i++) {
+ struct DataRace * race=unrealizedraces[i];
+ printRace(race);
+ }
+ return true;
}
}
+ return false;
}
void printRace(struct DataRace * race) {
void initRaceDetector();
void raceCheckWrite(thread_id_t thread, void *location, ClockVector *currClock);
void raceCheckRead(thread_id_t thread, void *location, ClockVector *currClock);
-void checkDataRaces();
+bool checkDataRaces();
void printRace(struct DataRace *race);
extern std::vector<struct DataRace *> unrealizedraces;
return get_next_replay_thread();
}
+/** @returns whether the current partial trace must be a prefix of a
+ * feasible trace. */
+
+bool ModelChecker::isfeasibleprefix() {
+}
+
/** @returns whether the current partial trace is feasible. */
bool ModelChecker::isfeasible() {
return !mo_graph->checkForCycles() && !failed_promise;
return Thread::swap(old, &system_context);
}
+void ModelChecker::assert_thread() {
+ DBG();
+ Thread *old = thread_current();
+ set_current_action(NULL);
+ old->set_state(THREAD_ASSERTED);
+ return Thread::swap(old, &system_context);
+}
+
/**
* Takes the next step in the execution, if possible.
* @return Returns true (success) if a step was taken and false otherwise.
} else if (curr->get_state() == THREAD_RUNNING) {
/* Stopped while running; i.e., completed */
curr->complete();
+ } else if (curr->get_state()==THREAD_ASSERTED) {
+ /* Something bad happened. Stop taking steps. */
+ return false;
} else {
ASSERT(false);
}
/** @return The currently executing Thread. */
Thread * get_current_thread() { return scheduler->get_current_thread(); }
+ void assert_thread();
int switch_to_master(ModelAction *act);
ClockVector * get_cv(thread_id_t tid);
ModelAction * get_parent_action(thread_id_t tid);
std::vector<const ModelAction *> *release_heads);
void finish_execution();
+ bool isfeasibleprefix();
MEMALLOC
private:
* context.
*/
THREAD_READY,
+ THREAD_ASSERTED,
/** Thread has completed its execution */
THREAD_COMPLETED
} thread_state;