if (!blocking->is_complete()) {
blocking->push_wait_list(curr);
scheduler->sleep(waiting);
+ } else {
+ do_complete_join(curr);
}
break;
}
ModelAction *act = th->pop_wait_list();
Thread *wake = get_thread(act);
scheduler->wake(wake);
+ do_complete_join(act);
}
th->complete();
break;
return get_next_thread(curr);
}
+/**
+ * Complete a THREAD_JOIN operation, by synchronizing with the THREAD_FINISH
+ * operation from the Thread it is joining with. Must be called after the
+ * completion of the Thread in question.
+ * @param join The THREAD_JOIN action
+ */
+void ModelChecker::do_complete_join(ModelAction *join)
+{
+ Thread *blocking = (Thread *)join->get_location();
+ ModelAction *act = get_last_action(blocking->get_id());
+ join->synchronize_with(act);
+}
+
void ModelChecker::check_curr_backtracking(ModelAction * curr) {
Node *currnode = curr->get_node();
Node *parnode = currnode->get_parent();
bool release_seq_head(const ModelAction *rf,
std::vector< const ModelAction *, MyAlloc<const ModelAction *> > *release_heads) const;
bool resolve_release_sequences(void *location, work_queue_t *work_queue);
+ void do_complete_join(ModelAction *join);
ModelAction *diverge;