/** Note that this value can be legitimately used by a program, and
hence by iteself does not indicate no value. */
/** Note that this value can be legitimately used by a program, and
hence by iteself does not indicate no value. */
/** @brief Represents an action type, identifying one of several types of
* ModelAction */
typedef enum action_type {
/** @brief Represents an action type, identifying one of several types of
* ModelAction */
typedef enum action_type {
THREAD_CREATE, /**< A thread creation action */
THREAD_START, /**< First action in each thread */
THREAD_YIELD, /**< A thread yield action */
THREAD_JOIN, /**< A thread join action */
THREAD_FINISH, /**< A thread completion action */
THREAD_CREATE, /**< A thread creation action */
THREAD_START, /**< First action in each thread */
THREAD_YIELD, /**< A thread yield action */
THREAD_JOIN, /**< A thread join action */
THREAD_FINISH, /**< A thread completion action */
ATOMIC_READ, /**< An atomic read action */
ATOMIC_WRITE, /**< An atomic write action */
ATOMIC_RMWR, /**< The read part of an atomic RMW action */
ATOMIC_READ, /**< An atomic read action */
ATOMIC_WRITE, /**< An atomic write action */
ATOMIC_RMWR, /**< The read part of an atomic RMW action */
ATOMIC_FENCE, /**< A fence action */
ATOMIC_LOCK, /**< A lock action */
ATOMIC_TRYLOCK, /**< A trylock action */
ATOMIC_FENCE, /**< A fence action */
ATOMIC_LOCK, /**< A lock action */
ATOMIC_TRYLOCK, /**< A trylock action */
- ATOMIC_UNLOCK /**< An unlock action */
+ ATOMIC_UNLOCK, /**< An unlock action */
+ ATOMIC_NOTIFY_ONE, /**< A notify_one action */
+ ATOMIC_NOTIFY_ALL, /**< A notify all action */
+ ATOMIC_WAIT /**< A wait action */
- ModelAction(action_type_t type, memory_order order, void *loc, uint64_t value = VALUE_NONE);
+ ModelAction(action_type_t type, memory_order order, void *loc, uint64_t value = VALUE_NONE, Thread *thread = NULL);
+ void set_read_from(const ModelAction *act);
+
+ /** Store the most recent fence-release from the same thread
+ * @param fence The fence-release that occured prior to this */
+ void set_last_fence_release(const ModelAction *fence) { last_fence_release = fence; }
+ /** @return The most recent fence-release from the same thread */
+ const ModelAction * get_last_fence_release() const { return last_fence_release; }
+
void copy_from_new(ModelAction *newaction);
void set_seq_number(modelclock_t num);
void set_try_lock(bool obtainedlock);
void copy_from_new(ModelAction *newaction);
void set_seq_number(modelclock_t num);
void set_try_lock(bool obtainedlock);
bool is_acquire() const;
bool is_release() const;
bool is_seqcst() const;
bool same_var(const ModelAction *act) const;
bool same_thread(const ModelAction *act) const;
bool is_conflicting_lock(const ModelAction *act) const;
bool is_acquire() const;
bool is_release() const;
bool is_seqcst() const;
bool same_var(const ModelAction *act) const;
bool same_thread(const ModelAction *act) const;
bool is_conflicting_lock(const ModelAction *act) const;
bool synchronize_with(const ModelAction *act);
bool has_synchronized_with(const ModelAction *act) const;
bool synchronize_with(const ModelAction *act);
bool has_synchronized_with(const ModelAction *act) const;
/** A back reference to a Node in NodeStack, if this ModelAction is
* saved on the NodeStack. */
Node *node;
/** A back reference to a Node in NodeStack, if this ModelAction is
* saved on the NodeStack. */
Node *node;