X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=action.cc;h=4de6f354bfbccfbedc9061538ecb48be8e69e3e2;hb=02558d484765370cd00ff15008412aa4a15eea11;hp=0a6a1dd26665a6d553b4e0b7c258f519330bba56;hpb=6bbd9b9dd928e62df9dffbf9027124112eec0576;p=model-checker.git diff --git a/action.cc b/action.cc index 0a6a1dd..4de6f35 100644 --- a/action.cc +++ b/action.cc @@ -1,7 +1,6 @@ #include #define __STDC_FORMAT_MACROS #include -#include #include "model.h" #include "action.h" @@ -151,6 +150,11 @@ bool ModelAction::could_be_write() const return is_write() || is_rmwr(); } +bool ModelAction::is_yield() const +{ + return type == THREAD_YIELD; +} + bool ModelAction::is_rmwr() const { return type == ATOMIC_RMWR; @@ -378,6 +382,64 @@ void ModelAction::set_try_lock(bool obtainedlock) { value = VALUE_TRYFAILED; } +/** + * @brief Get the value read by this load + * + * We differentiate this function from ModelAction::get_write_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 load. + * + * @return The value read by this load + */ +uint64_t ModelAction::get_reads_from_value() const +{ + 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 { @@ -510,14 +572,6 @@ void ModelAction::print() const type_str = "unknown type"; } - uint64_t valuetoprint; - if (is_read() && reads_from) - valuetoprint = reads_from->value; - else if (is_read() && reads_from_promise) - valuetoprint = reads_from_promise->get_value(); - else - valuetoprint = value; - switch (this->order) { case std::memory_order_relaxed: mo_str = "relaxed"; @@ -540,7 +594,7 @@ void ModelAction::print() const } model_print("(%4d) Thread: %-2d Action: %-13s MO: %7s Loc: %14p Value: %-#18" PRIx64, - seq_number, id_to_int(tid), type_str, mo_str, location, valuetoprint); + seq_number, id_to_int(tid), type_str, mo_str, location, get_return_value()); if (is_read()) { if (reads_from) model_print(" Rf: %-3d", reads_from->get_seq_number()); @@ -575,3 +629,43 @@ unsigned int ModelAction::hash() const hash ^= reads_from->get_seq_number(); 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; +} + +/** + * @brief Checks the NodeStack to see if a Promise is in our may-read-from set + * @param promise The Promise to check for + * @return True if the Promise is found; false otherwise + */ +bool ModelAction::may_read_from(const Promise *promise) const +{ + for (int i = 0; i < node->get_read_from_promise_size(); i++) + if (node->get_read_from_promise(i) == promise) + 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 + */ +std::mutex * ModelAction::get_mutex() const +{ + if (is_trylock() || is_lock() || is_unlock()) + return (std::mutex *)get_location(); + else if (is_wait()) + return (std::mutex *)get_value(); + else + return NULL; +}