X-Git-Url: http://plrg.eecs.uci.edu/git/?p=c11tester.git;a=blobdiff_plain;f=action.cc;h=ec7332dc696dc6221628e9139e004b59e8ac8d4d;hp=bbbeceea28cf7c683dced7d95111b624e00576ce;hb=0fd64e09bb7a48d62eb724507f8716f1af4dc8d7;hpb=89ecd60fab0d93d6df6aa35e663ab67db860fa1d diff --git a/action.cc b/action.cc index bbbeceea..ec7332dc 100644 --- a/action.cc +++ b/action.cc @@ -8,7 +8,6 @@ #include "clockvector.h" #include "common.h" #include "threads-model.h" -#include "nodestack.h" #include "wildcard.h" #define ACTION_INITIAL_CLOCK 0 @@ -33,25 +32,61 @@ */ ModelAction::ModelAction(action_type_t type, memory_order order, void *loc, uint64_t value, Thread *thread) : - type(type), - order(order), - original_order(order), location(loc), - value(value), + position(NULL), reads_from(NULL), last_fence_release(NULL), - node(NULL), - seq_number(ACTION_INITIAL_CLOCK), - cv(NULL) + uninitaction(NULL), + cv(NULL), + rf_cv(NULL), + trace_ref(NULL), + thrdmap_ref(NULL), + action_ref(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); Thread *t = thread ? thread : thread_current(); - this->tid = t->get_id(); + this->tid = t!= NULL ? t->get_id() : -1; } +/** + * @brief Construct a new ModelAction for sleep actions + * + * @param type The type of action: THREAD_SLEEP + * @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 The time duration a thread is scheduled to sleep. + * @param _time The this sleep action is constructed + */ +ModelAction::ModelAction(action_type_t type, memory_order order, uint64_t value, uint64_t _time) : + location(NULL), + position(NULL), + time(_time), + last_fence_release(NULL), + uninitaction(NULL), + cv(NULL), + rf_cv(NULL), + trace_ref(NULL), + thrdmap_ref(NULL), + action_ref(NULL), + value(value), + type(type), + order(order), + original_order(order), + seq_number(ACTION_INITIAL_CLOCK) +{ + Thread *t = thread_current(); + this->tid = t!= NULL ? t->get_id() : -1; +} + /** * @brief Construct a new ModelAction * @@ -66,16 +101,59 @@ ModelAction::ModelAction(action_type_t type, memory_order order, void *loc, */ 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), + uninitaction(NULL), + cv(NULL), + rf_cv(NULL), + trace_ref(NULL), + thrdmap_ref(NULL), + action_ref(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 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, const char * position, memory_order order, void *loc, + uint64_t value, int size) : location(loc), - value(value), + position(position), reads_from(NULL), last_fence_release(NULL), - node(NULL), - seq_number(ACTION_INITIAL_CLOCK), - cv(NULL) + uninitaction(NULL), + cv(NULL), + rf_cv(NULL), + trace_ref(NULL), + thrdmap_ref(NULL), + action_ref(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); @@ -84,6 +162,46 @@ ModelAction::ModelAction(action_type_t type, memory_order order, void *loc, 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), + uninitaction(NULL), + cv(NULL), + rf_cv(NULL), + trace_ref(NULL), + thrdmap_ref(NULL), + action_ref(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); + + Thread *t = thread ? thread : thread_current(); + this->tid = t->get_id(); +} + + /** @brief ModelAction destructor */ ModelAction::~ModelAction() { @@ -116,6 +234,11 @@ void ModelAction::set_seq_number(modelclock_t num) seq_number = num; } +void ModelAction::reset_seq_number() +{ + seq_number = 0; +} + bool ModelAction::is_thread_start() const { return type == THREAD_START; @@ -128,7 +251,7 @@ bool ModelAction::is_thread_join() const bool ModelAction::is_mutex_op() const { - return type == ATOMIC_LOCK || type == ATOMIC_TRYLOCK || type == ATOMIC_UNLOCK || type == ATOMIC_WAIT || type == ATOMIC_NOTIFY_ONE || type == ATOMIC_NOTIFY_ALL; + return type == ATOMIC_LOCK || type == ATOMIC_TRYLOCK || type == ATOMIC_UNLOCK || type == ATOMIC_WAIT || type == ATOMIC_TIMEDWAIT || type == ATOMIC_NOTIFY_ONE || type == ATOMIC_NOTIFY_ALL; } bool ModelAction::is_lock() const @@ -136,8 +259,13 @@ bool ModelAction::is_lock() const return type == ATOMIC_LOCK; } +bool ModelAction::is_sleep() const +{ + return type == THREAD_SLEEP; +} + bool ModelAction::is_wait() const { - return type == ATOMIC_WAIT; + return type == ATOMIC_WAIT || type == ATOMIC_TIMEDWAIT; } bool ModelAction::is_notify() const { @@ -186,7 +314,7 @@ bool ModelAction::is_read() const bool ModelAction::is_write() const { - return type == ATOMIC_WRITE || type == ATOMIC_RMW || type == ATOMIC_INIT || type == ATOMIC_UNINIT; + return type == ATOMIC_WRITE || type == ATOMIC_RMW || type == ATOMIC_INIT || type == ATOMIC_UNINIT || type == NONATOMIC_WRITE; } bool ModelAction::could_be_write() const @@ -465,7 +593,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 } /** @@ -505,29 +634,20 @@ uint64_t ModelAction::get_return_value() const return value; } -/** @return The Node associated with this ModelAction */ -Node * ModelAction::get_node() const -{ - /* UNINIT actions do not have a Node */ - ASSERT(!is_uninitialized()); - return node; -} - /** * Update the model action's read_from action * @param act The action to read from; should be a write */ -void ModelAction::set_read_from(const ModelAction *act) +void ModelAction::set_read_from(ModelAction *act) { ASSERT(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); - reads_from = (const ModelAction *)act_initialized; + ModelAction * act_uninitialized = (ModelAction *)act; + act_uninitialized->set_value(val); + reads_from = act_uninitialized; // disabled by WL, because LLVM IR is unable to detect atomic init /* model->assert_bug("May read from uninitialized atomic:\n" @@ -576,11 +696,14 @@ const char * ModelAction::get_type_str() const case THREAD_YIELD: return "thread yield"; case THREAD_JOIN: return "thread join"; case THREAD_FINISH: return "thread finish"; + case THREAD_SLEEP: return "thread sleep"; + case THREADONLY_FINISH: return "pthread_exit finish"; case PTHREAD_CREATE: return "pthread create"; case PTHREAD_JOIN: return "pthread join"; case ATOMIC_UNINIT: return "uninitialized"; + case NONATOMIC_WRITE: return "nonatomic write"; case ATOMIC_READ: return "atomic read"; case ATOMIC_WRITE: return "atomic write"; case ATOMIC_RMW: return "atomic rmw"; @@ -593,6 +716,7 @@ const char * ModelAction::get_type_str() const case ATOMIC_UNLOCK: return "unlock"; case ATOMIC_TRYLOCK: return "trylock"; case ATOMIC_WAIT: return "wait"; + case ATOMIC_TIMEDWAIT: return "timed wait"; case ATOMIC_NOTIFY_ONE: return "notify one"; case ATOMIC_NOTIFY_ALL: return "notify all"; case ATOMIC_ANNOTATION: return "annotation";