+}
+
+/**
+ * Processes a lock, trylock, or unlock model action. @param curr is
+ * the read model action to process.
+ *
+ * The try lock operation checks whether the lock is taken. If not,
+ * it falls to the normal lock operation case. If so, it returns
+ * fail.
+ *
+ * The lock operation has already been checked that it is enabled, so
+ * it just grabs the lock and synchronizes with the previous unlock.
+ *
+ * The unlock operation has to re-enable all of the threads that are
+ * waiting on the lock.
+ */
+
+void ModelChecker::process_mutex(ModelAction *curr) {
+ std::mutex * mutex=(std::mutex *) curr->get_location();
+ struct std::mutex_state * state=mutex->get_state();
+ switch(curr->get_type()) {
+ case ATOMIC_TRYLOCK: {
+ bool success=!state->islocked;
+ curr->set_try_lock(success);
+ if (!success) {
+ get_thread(curr)->set_return_value(0);
+ break;
+ }
+ get_thread(curr)->set_return_value(1);
+ }
+ //otherwise fall into the lock case
+ case ATOMIC_LOCK: {
+ if (curr->get_cv()->getClock(state->alloc_tid)<=state->alloc_clock) {
+ printf("Lock access before initialization\n");
+ set_assert();
+ }
+ state->islocked=true;
+ ModelAction *unlock=get_last_unlock(curr);
+ //synchronize with the previous unlock statement
+ if ( unlock != NULL )
+ curr->synchronize_with(unlock);
+ break;
+ }
+ case ATOMIC_UNLOCK: {
+ //unlock the lock
+ state->islocked=false;
+ //wake up the other threads
+ action_list_t * waiters = lock_waiters_map->get_safe_ptr(curr->get_location());
+ //activate all the waiting threads
+ for(action_list_t::iterator rit = waiters->begin(); rit!=waiters->end(); rit++) {
+ scheduler->add_thread(get_thread((*rit)->get_tid()));
+ }
+ waiters->clear();
+ break;
+ }
+ default:
+ ASSERT(0);
+ }
+}
+
+
+/**
+ * Process a write ModelAction
+ * @param curr The ModelAction to process
+ * @return True if the mo_graph was updated or promises were resolved
+ */
+bool ModelChecker::process_write(ModelAction *curr)
+{
+ bool updated_mod_order = w_modification_order(curr);
+ bool updated_promises = resolve_promises(curr);
+
+ if (promises->size() == 0) {
+ for (unsigned int i = 0; i<futurevalues->size(); i++) {
+ struct PendingFutureValue pfv = (*futurevalues)[i];
+ if (pfv.act->get_node()->add_future_value(pfv.value, pfv.expiration) &&
+ (!priv->next_backtrack || *pfv.act > *priv->next_backtrack))
+ priv->next_backtrack = pfv.act;
+ }
+ futurevalues->resize(0);
+ }
+
+ mo_graph->commitChanges();
+ get_thread(curr)->set_return_value(VALUE_NONE);
+ return updated_mod_order || updated_promises;
+}
+
+/**
+ * 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;