X-Git-Url: http://plrg.eecs.uci.edu/git/?p=c11tester.git;a=blobdiff_plain;f=action.cc;h=9a816de3837028c1dcec90d669237f8ba095fd49;hp=bd95850579548123d24288f1c8e3a312d44b83f8;hb=5e7a1a00c4645f90d860274e2f25c33992c2ad86;hpb=82f6d9ab97a87e874fb1b5dfa237266f4bfc95d1 diff --git a/action.cc b/action.cc index bd958505..9a816de3 100644 --- a/action.cc +++ b/action.cc @@ -32,26 +32,97 @@ * (default), then a Thread is assigned according to the scheduler. */ ModelAction::ModelAction(action_type_t type, memory_order order, void *loc, - uint64_t value, Thread *thread) : + uint64_t value, Thread *thread) : + location(loc), + position(NULL), + reads_from(NULL), + last_fence_release(NULL), + node(NULL), + cv(NULL), + value(value), type(type), order(order), original_order(order), + seq_number(ACTION_INITIAL_CLOCK) +{ + /* References to NULL atomic variables can end up here */ + ASSERT(loc || type == ATOMIC_FENCE || type == NOOP); + + Thread *t = thread ? thread : thread_current(); + this->tid = t->get_id(); +} + + +/** + * @brief Construct a new ModelAction + * + * @param type The type of action + * @param order The memory order of this action. A "don't care" for non-ATOMIC + * actions (e.g., THREAD_* or MODEL_* actions). + * @param loc The location that this action acts upon + * @param value (optional) A value associated with the action (e.g., the value + * read or written). Defaults to a given macro constant, for debugging purposes. + * @param size (optional) The Thread in which this action occurred. If NULL + * (default), then a Thread is assigned according to the scheduler. + */ +ModelAction::ModelAction(action_type_t type, memory_order order, void *loc, + uint64_t value, int size) : location(loc), + position(NULL), + reads_from(NULL), + last_fence_release(NULL), + node(NULL), + cv(NULL), value(value), + type(type), + order(order), + original_order(order), + seq_number(ACTION_INITIAL_CLOCK) +{ + /* References to NULL atomic variables can end up here */ + ASSERT(loc); + this->size = size; + Thread *t = thread_current(); + this->tid = t->get_id(); +} + + +/** + * @brief Construct a new ModelAction with source line number (requires llvm support) + * + * @param type The type of action + * @param position The source line number of this atomic operation + * @param order The memory order of this action. A "don't care" for non-ATOMIC + * actions (e.g., THREAD_* or MODEL_* actions). + * @param loc The location that this action acts upon + * @param value (optional) A value associated with the action (e.g., the value + * read or written). Defaults to a given macro constant, for debugging purposes. + * @param thread (optional) The Thread in which this action occurred. If NULL + * (default), then a Thread is assigned according to the scheduler. + */ +ModelAction::ModelAction(action_type_t type, const char * position, memory_order order, + void *loc, uint64_t value, Thread *thread) : + location(loc), + position(position), reads_from(NULL), last_fence_release(NULL), node(NULL), - seq_number(ACTION_INITIAL_CLOCK), cv(NULL), - sleep_flag(false) + value(value), + type(type), + order(order), + original_order(order), + seq_number(ACTION_INITIAL_CLOCK) { /* References to NULL atomic variables can end up here */ ASSERT(loc || type == ATOMIC_FENCE); Thread *t = thread ? thread : thread_current(); this->tid = t->get_id(); + // model_print("position: %s\n", position); } + /** @brief ModelAction destructor */ ModelAction::~ModelAction() { @@ -63,8 +134,12 @@ ModelAction::~ModelAction() */ /* - if (cv) - delete cv; */ + if (cv) + delete cv; */ +} + +int ModelAction::getSize() const { + return size; } void ModelAction::copy_from_new(ModelAction *newaction) @@ -145,7 +220,7 @@ bool ModelAction::is_uninitialized() const bool ModelAction::is_read() const { - return type == ATOMIC_READ || type == ATOMIC_RMWR || type == ATOMIC_RMW; + return type == ATOMIC_READ || type == ATOMIC_RMWR || type == ATOMIC_RMWRCAS || type == ATOMIC_RMW; } bool ModelAction::is_write() const @@ -165,7 +240,12 @@ bool ModelAction::is_yield() const bool ModelAction::is_rmwr() const { - return type == ATOMIC_RMWR; + return type == ATOMIC_RMWR || type == ATOMIC_RMWRCAS; +} + +bool ModelAction::is_rmwrcas() const +{ + return type == ATOMIC_RMWRCAS; } bool ModelAction::is_rmw() const @@ -424,7 +504,8 @@ uint64_t ModelAction::get_reads_from_value() const ASSERT(is_read()); if (reads_from) return reads_from->get_write_value(); - return VALUE_NONE; /* Only for new actions with no reads-from */ + + return VALUE_NONE; // Only for new actions with no reads-from } /** @@ -482,7 +563,7 @@ void ModelAction::set_read_from(const ModelAction *act) reads_from = act; - if (act->is_uninitialized()) { // WL + if (act->is_uninitialized()) { // WL uint64_t val = *((uint64_t *) location); ModelAction * act_initialized = (ModelAction *)act; act_initialized->set_value(val); @@ -490,10 +571,10 @@ void ModelAction::set_read_from(const ModelAction *act) // disabled by WL, because LLVM IR is unable to detect atomic init /* model->assert_bug("May read from uninitialized atomic:\n" - " action %d, thread %d, location %p (%s, %s)", - seq_number, id_to_int(tid), location, - get_type_str(), get_mo_str()); -*/ + " action %d, thread %d, location %p (%s, %s)", + seq_number, id_to_int(tid), location, + get_type_str(), get_mo_str()); + */ } } @@ -530,43 +611,44 @@ bool ModelAction::happens_before(const ModelAction *act) const const char * ModelAction::get_type_str() const { switch (this->type) { - case THREAD_CREATE: return "thread create"; - case THREAD_START: return "thread start"; - case THREAD_YIELD: return "thread yield"; - case THREAD_JOIN: return "thread join"; - case THREAD_FINISH: return "thread finish"; - - case PTHREAD_CREATE: return "pthread create"; - case PTHREAD_JOIN: return "pthread join"; - - case ATOMIC_UNINIT: return "uninitialized"; - case ATOMIC_READ: return "atomic read"; - case ATOMIC_WRITE: return "atomic write"; - case ATOMIC_RMW: return "atomic rmw"; - case ATOMIC_FENCE: return "fence"; - case ATOMIC_RMWR: return "atomic rmwr"; - case ATOMIC_RMWC: return "atomic rmwc"; - case ATOMIC_INIT: return "init atomic"; - case ATOMIC_LOCK: return "lock"; - case ATOMIC_UNLOCK: return "unlock"; - case ATOMIC_TRYLOCK: return "trylock"; - case ATOMIC_WAIT: return "wait"; - case ATOMIC_NOTIFY_ONE: return "notify one"; - case ATOMIC_NOTIFY_ALL: return "notify all"; - case ATOMIC_ANNOTATION: return "annotation"; - default: return "unknown type"; + case THREAD_CREATE: return "thread create"; + case THREAD_START: return "thread start"; + case THREAD_YIELD: return "thread yield"; + case THREAD_JOIN: return "thread join"; + case THREAD_FINISH: return "thread finish"; + + case PTHREAD_CREATE: return "pthread create"; + case PTHREAD_JOIN: return "pthread join"; + + case ATOMIC_UNINIT: return "uninitialized"; + case ATOMIC_READ: return "atomic read"; + case ATOMIC_WRITE: return "atomic write"; + case ATOMIC_RMW: return "atomic rmw"; + case ATOMIC_FENCE: return "fence"; + case ATOMIC_RMWR: return "atomic rmwr"; + case ATOMIC_RMWRCAS: return "atomic rmwrcas"; + case ATOMIC_RMWC: return "atomic rmwc"; + case ATOMIC_INIT: return "init atomic"; + case ATOMIC_LOCK: return "lock"; + case ATOMIC_UNLOCK: return "unlock"; + case ATOMIC_TRYLOCK: return "trylock"; + case ATOMIC_WAIT: return "wait"; + case ATOMIC_NOTIFY_ONE: return "notify one"; + case ATOMIC_NOTIFY_ALL: return "notify all"; + case ATOMIC_ANNOTATION: return "annotation"; + default: return "unknown type"; }; } const char * ModelAction::get_mo_str() const { switch (this->order) { - case std::memory_order_relaxed: return "relaxed"; - case std::memory_order_acquire: return "acquire"; - case std::memory_order_release: return "release"; - case std::memory_order_acq_rel: return "acq_rel"; - case std::memory_order_seq_cst: return "seq_cst"; - default: return "unknown"; + case std::memory_order_relaxed: return "relaxed"; + case std::memory_order_acquire: return "acquire"; + case std::memory_order_release: return "release"; + case std::memory_order_acq_rel: return "acq_rel"; + case std::memory_order_seq_cst: return "seq_cst"; + default: return "unknown"; } } @@ -576,7 +658,7 @@ void ModelAction::print() const const char *type_str = get_type_str(), *mo_str = get_mo_str(); model_print("%-4d %-2d %-14s %7s %14p %-#18" PRIx64, - seq_number, id_to_int(tid), type_str, mo_str, location, get_return_value()); + seq_number, id_to_int(tid), type_str, mo_str, location, get_return_value()); if (is_read()) { if (reads_from) model_print(" %-3d", reads_from->get_seq_number()); @@ -602,26 +684,13 @@ unsigned int ModelAction::hash() const hash ^= id_to_int(tid) << 6; if (is_read()) { - if (reads_from) - hash ^= reads_from->get_seq_number(); - hash ^= get_reads_from_value(); + if (reads_from) + hash ^= reads_from->get_seq_number(); + hash ^= get_reads_from_value(); } return hash; } -/** - * @brief Checks the NodeStack to see if a ModelAction is in our may-read-from set - * @param write The ModelAction to check for - * @return True if the ModelAction is found; false otherwise - */ -bool ModelAction::may_read_from(const ModelAction *write) const -{ - for (int i = 0; i < node->get_read_from_past_size(); i++) - if (node->get_read_from_past(i) == write) - return true; - return false; -} - /** * Only valid for LOCK, TRY_LOCK, UNLOCK, and WAIT operations. * @return The mutex operated on by this action, if any; otherwise NULL