X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=action.cc;h=6ae1d861150151133b7b878525705aac9fa5e910;hb=40212bad619f289d5c5ae944da42c80af249763d;hp=eb2f0c61f024e64fed76bc85131c47193cfe4d8f;hpb=10de861d3a9908e75b6f94283cc67b3f1b4d93ab;p=model-checker.git diff --git a/action.cc b/action.cc index eb2f0c6..6ae1d86 100644 --- a/action.cc +++ b/action.cc @@ -2,6 +2,8 @@ #include "model.h" #include "action.h" +#include "clockvector.h" +#include "common.h" ModelAction::ModelAction(action_type_t type, memory_order order, void *loc, int value) { @@ -14,6 +16,14 @@ ModelAction::ModelAction(action_type_t type, memory_order order, void *loc, int act->tid = t->get_id(); act->value = value; act->seq_number = model->get_next_seq_num(); + + cv = NULL; +} + +ModelAction::~ModelAction() +{ + if (cv) + delete cv; } bool ModelAction::is_read() @@ -26,6 +36,11 @@ bool ModelAction::is_write() return type == ATOMIC_WRITE; } +bool ModelAction::is_rmw() +{ + return type == ATOMIC_RMW; +} + bool ModelAction::is_acquire() { switch (order) { @@ -50,10 +65,14 @@ bool ModelAction::is_release() } } +bool ModelAction::is_seqcst() +{ + return order==memory_order_seq_cst; +} + bool ModelAction::same_var(ModelAction *act) { - return true; - // TODO: fix stack allocation... return location == act->location; + return location == act->location; } bool ModelAction::same_thread(ModelAction *act) @@ -61,18 +80,60 @@ bool ModelAction::same_thread(ModelAction *act) return tid == act->tid; } -bool ModelAction::is_dependent(ModelAction *act) +/** The is_synchronizing method should only explore interleavings if: + * (1) the operations are seq_cst and don't commute or + * (2) the reordering may establish or break a synchronization relation. + * Other memory operations will be dealt with by using the reads_from + * relation. + * + * @param act is the action to consider exploring a reordering. + * @return tells whether we have to explore a reordering. + */ + +bool ModelAction::is_synchronizing(ModelAction *act) { - if (!is_read() && !is_write()) + //Same thread can't be reordered + if (same_thread(act)) return false; - if (!act->is_read() && !act->is_write()) + + // Different locations commute + if (!same_var(act)) return false; - if (same_var(act) && !same_thread(act) && - (is_write() || act->is_write())) + + // Explore interleavings of seqcst writes to guarantee total order + // of seq_cst operations that don't commute + if (is_write() && is_seqcst() && act->is_write() && act->is_seqcst()) return true; + + // Explore synchronizing read/write pairs + if (is_read() && is_acquire() && act->is_write() && act->is_release()) + return true; + if (is_write() && is_release() && act->is_read() && act->is_acquire()) + return true; + + // Otherwise handle by reads_from relation return false; } +void ModelAction::create_cv(ModelAction *parent) +{ + if (cv) + return; + + if (parent) + cv = new ClockVector(parent->cv, this); + else + cv = new ClockVector(NULL, this); +} + +void ModelAction::read_from(ModelAction *act) +{ + ASSERT(cv); + if (act->is_release() && this->is_acquire()) + cv->merge(act->cv); + value = act->value; +} + void ModelAction::print(void) { const char *type_str; @@ -92,10 +153,18 @@ void ModelAction::print(void) case ATOMIC_WRITE: type_str = "atomic write"; break; + case ATOMIC_RMW: + type_str = "atomic rmw"; + break; default: type_str = "unknown type"; } - printf("(%4d) Thread: %d\tAction: %s\tMO: %d\tLoc: %14p\tValue: %d\n", + printf("(%3d) Thread: %-2d Action: %-13s MO: %d Loc: %14p Value: %d", seq_number, id_to_int(tid), type_str, order, location, value); + if (cv) { + printf("\t"); + cv->print(); + } else + printf("\n"); }