action: refactor ATOMIC_READ printing
[model-checker.git] / action.cc
index 5ecc1f0e1b26f069650a47e139858eef68e05595..a11467587901f258a03b9e11623403f60f3d1263 100644 (file)
--- a/action.cc
+++ b/action.cc
@@ -66,10 +66,17 @@ void ModelAction::copy_from_new(ModelAction *newaction)
 
 void ModelAction::set_seq_number(modelclock_t num)
 {
+       /* ATOMIC_UNINIT actions should never have non-zero clock */
+       ASSERT(!is_uninitialized());
        ASSERT(seq_number == ACTION_INITIAL_CLOCK);
        seq_number = num;
 }
 
+bool ModelAction::is_thread_start() const
+{
+       return type == THREAD_START;
+}
+
 bool ModelAction::is_relseq_fixup() const
 {
        return type == MODEL_FIXUP_RELSEQ;
@@ -117,6 +124,17 @@ bool ModelAction::is_failed_trylock() const
        return (type == ATOMIC_TRYLOCK && value == VALUE_TRYFAILED);
 }
 
+/** @return True if this operation is performed on a C/C++ atomic variable */
+bool ModelAction::is_atomic_var() const
+{
+       return is_read() || could_be_write();
+}
+
+bool ModelAction::is_uninitialized() const
+{
+       return type == ATOMIC_UNINIT;
+}
+
 bool ModelAction::is_read() const
 {
        return type == ATOMIC_READ || type == ATOMIC_RMWR || type == ATOMIC_RMW;
@@ -124,7 +142,7 @@ bool ModelAction::is_read() const
 
 bool ModelAction::is_write() const
 {
-       return type == ATOMIC_WRITE || type == ATOMIC_RMW || type == ATOMIC_INIT;
+       return type == ATOMIC_WRITE || type == ATOMIC_RMW || type == ATOMIC_INIT || type == ATOMIC_UNINIT;
 }
 
 bool ModelAction::could_be_write() const
@@ -246,7 +264,7 @@ void ModelAction::process_rmw(ModelAction * act) {
  */
 bool ModelAction::could_synchronize_with(const ModelAction *act) const
 {
-       //Same thread can't be reordered
+       // Same thread can't be reordered
        if (same_thread(act))
                return false;
 
@@ -265,15 +283,15 @@ bool ModelAction::could_synchronize_with(const ModelAction *act) const
                        (act->could_be_write() || act->is_fence()))
                return true;
 
-       //lock just released...we can grab lock
+       // lock just released...we can grab lock
        if ((is_lock() ||is_trylock()) && (act->is_unlock()||act->is_wait()))
                return true;
 
-       //lock just acquired...we can fail to grab lock
+       // lock just acquired...we can fail to grab lock
        if (is_trylock() && act->is_success_lock())
                return true;
 
-       //other thread stalling on lock...we can release lock
+       // other thread stalling on lock...we can release lock
        if (is_unlock() && (act->is_trylock()||act->is_lock()))
                return true;
 
@@ -292,19 +310,19 @@ bool ModelAction::could_synchronize_with(const ModelAction *act) const
 
 bool ModelAction::is_conflicting_lock(const ModelAction *act) const
 {
-       //Must be different threads to reorder
+       // Must be different threads to reorder
        if (same_thread(act))
                return false;
        
-       //Try to reorder a lock past a successful lock
+       // Try to reorder a lock past a successful lock
        if (act->is_success_lock())
                return true;
        
-       //Try to push a successful trylock past an unlock
+       // Try to push a successful trylock past an unlock
        if (act->is_unlock() && is_trylock() && value == VALUE_TRYSUCCESS)
                return true;
 
-       //Try to push a successful trylock past a wait
+       // Try to push a successful trylock past a wait
        if (act->is_wait() && is_trylock() && value == VALUE_TRYSUCCESS)
                return true;
 
@@ -334,27 +352,23 @@ void ModelAction::set_try_lock(bool obtainedlock) {
                value=VALUE_TRYFAILED;
 }
 
+/** @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
- * @return True if this read established synchronization
  */
-bool ModelAction::read_from(const ModelAction *act)
+void ModelAction::set_read_from(const ModelAction *act)
 {
-       ASSERT(cv);
        reads_from = act;
-       if (act != NULL && this->is_acquire()) {
-               rel_heads_list_t release_heads;
-               model->get_release_seq_heads(this, &release_heads);
-               int num_heads = release_heads.size();
-               for (unsigned int i = 0; i < release_heads.size(); i++)
-                       if (!synchronize_with(release_heads[i])) {
-                               model->set_bad_synchronization();
-                               num_heads--;
-                       }
-               return num_heads > 0;
-       }
-       return false;
+       if (act && act->is_uninitialized())
+               model->assert_bug("May read from uninitialized atomic\n");
 }
 
 /**
@@ -410,6 +424,9 @@ void ModelAction::print() const
        case THREAD_FINISH:
                type_str = "thread finish";
                break;
+       case ATOMIC_UNINIT:
+               type_str = "uninitialized";
+               break;
        case ATOMIC_READ:
                type_str = "atomic read";
                break;
@@ -453,7 +470,11 @@ void ModelAction::print() const
                type_str = "unknown type";
        }
 
-       uint64_t valuetoprint=type==ATOMIC_READ?(reads_from!=NULL?reads_from->value:VALUE_NONE):value;
+       uint64_t valuetoprint;
+       if (type == ATOMIC_READ && reads_from != NULL)
+               valuetoprint = reads_from->value;
+       else
+               valuetoprint = value;
 
        switch (this->order) {
        case std::memory_order_relaxed: