+ ASSERT(is_read());
+ if (reads_from)
+ return reads_from->get_write_value();
+ else if (reads_from_promise)
+ return reads_from_promise->get_value();
+ return VALUE_NONE; /* Only for new actions with no reads-from */
+}
+
+/**
+ * @brief Get the value written by this store
+ *
+ * We differentiate this function from ModelAction::get_reads_from_value and
+ * ModelAction::get_value for the purpose of RMW's, which may have both a
+ * 'read' and a 'write' value.
+ *
+ * Note: 'this' must be a store.
+ *
+ * @return The value written by this store
+ */
+uint64_t ModelAction::get_write_value() const
+{
+ ASSERT(is_write());
+ return value;
+}
+
+/**
+ * @brief Get the value returned by this action
+ *
+ * For atomic reads (including RMW), an operation returns the value it read.
+ * For atomic writes, an operation returns the value it wrote. For other
+ * operations, the return value varies (sometimes is a "don't care"), but the
+ * value is simply stored in the "value" field.
+ *
+ * @return This action's return value
+ */
+uint64_t ModelAction::get_return_value() const
+{
+ if (is_read())
+ return get_reads_from_value();
+ else if (is_write())
+ return get_write_value();
+ else
+ 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)
+{
+ ASSERT(act);
+ reads_from = act;
+ reads_from_promise = NULL;
+ if (act->is_uninitialized())
+ model->assert_bug("May read from uninitialized atomic\n");
+}
+
+/**
+ * Set this action's read-from promise
+ * @param promise The promise to read from
+ */
+void ModelAction::set_read_from_promise(Promise *promise)
+{
+ ASSERT(is_read());
+ reads_from_promise = promise;
+ reads_from = NULL;
+}
+
+/**
+ * Synchronize the current thread with the thread corresponding to the
+ * ModelAction parameter.
+ * @param act The ModelAction to synchronize with
+ * @return True if this is a valid synchronization; false otherwise
+ */
+bool ModelAction::synchronize_with(const ModelAction *act)
+{
+ if (*this < *act)
+ return false;
+ cv->merge(act->cv);
+ return true;
+}
+
+bool ModelAction::has_synchronized_with(const ModelAction *act) const
+{
+ return cv->synchronized_since(act);