break;
}
case WORK_CHECK_RELEASE_SEQ:
- resolve_release_sequences(work.location);
+ resolve_release_sequences(work.location, &work_queue);
break;
case WORK_CHECK_MO_EDGES:
/** @todo Perform follow-up mo_graph checks */
*
* @param location The location/object that should be checked for release
* sequence resolutions
- * @return True if any updates occurred (new synchronization, new mo_graph edges)
+ * @param work_queue The work queue to which to add work items as they are
+ * generated
+ * @return True if any updates occurred (new synchronization, new mo_graph
+ * edges)
*/
-bool ModelChecker::resolve_release_sequences(void *location)
+bool ModelChecker::resolve_release_sequences(void *location, work_queue_t *work_queue)
{
std::list<ModelAction *> *list;
list = lazy_sync_with_release->getptr(location);
}
if (updated) {
+ /* Re-check act for mo_graph edges */
+ work_queue->push_back(MOEdgeWorkEntry(act));
+
/* propagate synchronization to later actions */
action_list_t::reverse_iterator it = action_trace->rbegin();
while ((*it) != act) {
ModelAction *propagate = *it;
- if (act->happens_before(propagate))
- /** @todo new mo_graph edges along with
- * this synchronization? */
+ if (act->happens_before(propagate)) {
propagate->synchronize_with(act);
+ /* Re-check 'propagate' for mo_graph edges */
+ work_queue->push_back(MOEdgeWorkEntry(propagate));
+ }
}
}
if (complete) {
bool w_modification_order(ModelAction *curr);
bool release_seq_head(const ModelAction *rf,
std::vector< const ModelAction *, MyAlloc<const ModelAction *> > *release_heads) const;
- bool resolve_release_sequences(void *location);
+ bool resolve_release_sequences(void *location, work_queue_t *work_queue);
ModelAction *diverge;