+/**
+ * Initialize the current action by performing one or more of the following
+ * actions, as appropriate: merging RMWR and RMWC/RMW actions, stepping forward
+ * in the NodeStack, manipulating backtracking sets, allocating and
+ * initializing clock vectors, and computing the promises to fulfill.
+ *
+ * @param curr The current action, as passed from the user context; may be
+ * freed/invalidated after the execution of this function
+ * @return The current action, as processed by the ModelChecker. Is only the
+ * same as the parameter @a curr if this is a newly-explored action.
+ */
+ModelAction * ModelChecker::initialize_curr_action(ModelAction *curr)
+{
+ ModelAction *newcurr;
+
+ if (curr->is_rmwc() || curr->is_rmw()) {
+ newcurr = process_rmw(curr);
+ delete curr;
+ compute_promises(newcurr);
+ return newcurr;
+ }
+
+ newcurr = node_stack->explore_action(curr, scheduler->get_enabled());
+ if (newcurr) {
+ /* First restore type and order in case of RMW operation */
+ if (curr->is_rmwr())
+ newcurr->copy_typeandorder(curr);
+
+ ASSERT(curr->get_location() == newcurr->get_location());
+ newcurr->copy_from_new(curr);
+
+ /* Discard duplicate ModelAction; use action from NodeStack */
+ delete curr;
+
+ /* If we have diverged, we need to reset the clock vector. */
+ if (diverge == NULL)
+ newcurr->create_cv(get_parent_action(newcurr->get_tid()));
+ } else {
+ newcurr = curr;
+ /*
+ * Perform one-time actions when pushing new ModelAction onto
+ * NodeStack
+ */
+ curr->create_cv(get_parent_action(curr->get_tid()));
+ if (curr->is_write())
+ compute_promises(curr);
+ }
+ return newcurr;
+}
+
+/**
+ * This method checks whether a model action is enabled at the given point.
+ * At this point, it checks whether a lock operation would be successful at this point.
+ * If not, it puts the thread in a waiter list.
+ * @param curr is the ModelAction to check whether it is enabled.
+ * @return a bool that indicates whether the action is enabled.
+ */
+
+bool ModelChecker::check_action_enabled(ModelAction *curr) {
+ if (curr->is_lock()) {
+ std::mutex * lock = (std::mutex *)curr->get_location();
+ struct std::mutex_state * state = lock->get_state();
+ if (state->islocked) {
+ //Stick the action in the appropriate waiting queue
+ lock_waiters_map->get_safe_ptr(curr->get_location())->push_back(curr);
+ return false;
+ }
+ }
+
+ return true;
+}
+