From: Brian Norris <banorris@uci.edu>
Date: Wed, 8 May 2013 17:05:44 +0000 (-0700)
Subject: execution: refactor common CV propagation into its own function
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=dd1f275d3e8042282bad49cf85fddfc2a5735166;p=cdsspec-compiler.git

execution: refactor common CV propagation into its own function

There are a few occasions where we want to "fixup" a series of clock
vectors after establishing lazy synchronization (and one place where we
currently have a bug). Refactor this out to its own function so I can
reuse it elsewhere.
---

diff --git a/execution.cc b/execution.cc
index f2c50c4..4e15427 100644
--- a/execution.cc
+++ b/execution.cc
@@ -1025,21 +1025,9 @@ void ModelExecution::process_relseq_fixup(ModelAction *curr, work_queue_t *work_
 		/* Must synchronize */
 		if (!synchronize(release, acquire))
 			return;
-		/* Re-check all pending release sequences */
-		work_queue->push_back(CheckRelSeqWorkEntry(NULL));
-		/* Re-check act for mo_graph edges */
-		work_queue->push_back(MOEdgeWorkEntry(acquire));
-
-		/* propagate synchronization to later actions */
-		action_list_t::reverse_iterator rit = action_trace.rbegin();
-		for (; (*rit) != acquire; rit++) {
-			ModelAction *propagate = *rit;
-			if (acquire->happens_before(propagate)) {
-				synchronize(acquire, propagate);
-				/* Re-check 'propagate' for mo_graph edges */
-				work_queue->push_back(MOEdgeWorkEntry(propagate));
-			}
-		}
+
+		/* Propagate the changed clock vector */
+		propagate_clockvector(acquire, work_queue);
 	} else {
 		/* Break release sequence with new edges:
 		 *   release --mo--> write --mo--> rf */
@@ -2062,6 +2050,37 @@ void ModelExecution::get_release_seq_heads(ModelAction *acquire,
 	}
 }
 
+/**
+ * @brief Propagate a modified clock vector to actions later in the execution
+ * order
+ *
+ * After an acquire operation lazily completes a release-sequence
+ * synchronization, we must update all clock vectors for operations later than
+ * the acquire in the execution order.
+ *
+ * @param acquire The ModelAction whose clock vector must be propagated
+ * @param work The work queue to which we can add work items, if this
+ * propagation triggers more updates (e.g., to the modification order)
+ */
+void ModelExecution::propagate_clockvector(ModelAction *acquire, work_queue_t *work)
+{
+	/* Re-check all pending release sequences */
+	work->push_back(CheckRelSeqWorkEntry(NULL));
+	/* Re-check read-acquire for mo_graph edges */
+	work->push_back(MOEdgeWorkEntry(acquire));
+
+	/* propagate synchronization to later actions */
+	action_list_t::reverse_iterator rit = action_trace.rbegin();
+	for (; (*rit) != acquire; rit++) {
+		ModelAction *propagate = *rit;
+		if (acquire->happens_before(propagate)) {
+			synchronize(acquire, propagate);
+			/* Re-check 'propagate' for mo_graph edges */
+			work->push_back(MOEdgeWorkEntry(propagate));
+		}
+	}
+}
+
 /**
  * Attempt to resolve all stashed operations that might synchronize with a
  * release sequence for a given location. This implements the "lazy" portion of
@@ -2100,22 +2119,8 @@ bool ModelExecution::resolve_release_sequences(void *location, work_queue_t *wor
 					updated = true;
 
 		if (updated) {
-			/* Re-check all pending release sequences */
-			work_queue->push_back(CheckRelSeqWorkEntry(NULL));
-			/* Re-check read-acquire for mo_graph edges */
-			if (acquire->is_read())
-				work_queue->push_back(MOEdgeWorkEntry(acquire));
-
-			/* propagate synchronization to later actions */
-			action_list_t::reverse_iterator rit = action_trace.rbegin();
-			for (; (*rit) != acquire; rit++) {
-				ModelAction *propagate = *rit;
-				if (acquire->happens_before(propagate)) {
-					synchronize(acquire, propagate);
-					/* Re-check 'propagate' for mo_graph edges */
-					work_queue->push_back(MOEdgeWorkEntry(propagate));
-				}
-			}
+			/* Propagate the changed clock vector */
+			propagate_clockvector(acquire, work_queue);
 		}
 		if (complete) {
 			it = pending_rel_seqs.erase(it);
diff --git a/execution.h b/execution.h
index 7f63e6d..bb4ebb0 100644
--- a/execution.h
+++ b/execution.h
@@ -183,6 +183,7 @@ private:
 	bool w_modification_order(ModelAction *curr, ModelVector<ModelAction *> *send_fv);
 	void get_release_seq_heads(ModelAction *acquire, ModelAction *read, rel_heads_list_t *release_heads);
 	bool release_seq_heads(const ModelAction *rf, rel_heads_list_t *release_heads, struct release_seq *pending) const;
+	void propagate_clockvector(ModelAction *acquire, work_queue_t *work);
 	bool resolve_release_sequences(void *location, work_queue_t *work_queue);
 	void add_future_value(const ModelAction *writer, ModelAction *reader);