model: utilize bad_synchronization flag
[c11tester.git] / action.cc
index e5c9afe46f4cd81fff20555344b669c23c9b4bb1..c744c65f1b5b06223ea08618c3ea1d1700b6c500 100644 (file)
--- a/action.cc
+++ b/action.cc
@@ -27,6 +27,10 @@ ModelAction::~ModelAction()
                delete cv;
 }
 
+void ModelAction::copy_from_new(ModelAction *newaction) {
+       seq_number=newaction->seq_number;
+}
+
 bool ModelAction::is_mutex_op() const {
        return type == ATOMIC_LOCK || type == ATOMIC_TRYLOCK || type == ATOMIC_UNLOCK;
 }
@@ -180,6 +184,23 @@ bool ModelAction::is_synchronizing(const ModelAction *act) const
        return false;
 }
 
+bool ModelAction::is_conflicting_lock(const ModelAction *act) const
+{
+       //Must be different threads to reorder
+       if (same_thread(act))
+               return false;
+       
+       //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
+       if (act->is_unlock() && is_trylock() && value == VALUE_TRYSUCCESS)
+               return true;
+
+       return false;
+}
+
 void ModelAction::create_cv(const ModelAction *parent)
 {
        if (cv)
@@ -207,7 +228,8 @@ void ModelAction::read_from(const ModelAction *act)
                rel_heads_list_t release_heads;
                model->get_release_seq_heads(this, &release_heads);
                for (unsigned int i = 0; i < release_heads.size(); i++)
-                       synchronize_with(release_heads[i]);
+                       if (!synchronize_with(release_heads[i]))
+                               model->set_bad_synchronization();
        }
 }
 
@@ -215,11 +237,14 @@ void ModelAction::read_from(const ModelAction *act)
  * 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
  */
-void ModelAction::synchronize_with(const ModelAction *act) {
-       ASSERT(*act < *this || type == THREAD_JOIN || type == ATOMIC_LOCK );
+bool ModelAction::synchronize_with(const ModelAction *act) {
+       if (*this < *act && type != THREAD_JOIN && type != ATOMIC_LOCK)
+               return false;
        model->check_promises(cv, act->cv);
        cv->merge(act->cv);
+       return true;
 }
 
 bool ModelAction::has_synchronized_with(const ModelAction *act) const
@@ -278,6 +303,15 @@ void ModelAction::print(void) const
        case ATOMIC_INIT:
                type_str = "init atomic";
                break;
+       case ATOMIC_LOCK:
+               type_str = "lock";
+               break;
+       case ATOMIC_UNLOCK:
+               type_str = "unlock";
+               break;
+       case ATOMIC_TRYLOCK:
+               type_str = "trylock";
+               break;
        default:
                type_str = "unknown type";
        }