From: Brian Norris Date: Tue, 4 Dec 2012 02:30:18 +0000 (-0800) Subject: model: add process_fence() X-Git-Url: http://plrg.eecs.uci.edu/git/?p=c11tester.git;a=commitdiff_plain;h=53f0d3f9d56fd6341ef725ce8651661d6d9d906e;hp=20f8e2bc8677046c4bd7cb0bb80696ced41301f2;ds=sidebyside model: add process_fence() process_fence() will only handle fence-acquire. Fence-relaxed is a no-op; fence-release is only logged for later use; and fence-seq-cst takes release/acquire semantics, plus some mo-graph rules which apply to reads/reads (see {r,w}_modification_order). --- diff --git a/model.cc b/model.cc index dbca58e7..6120f4d4 100644 --- a/model.cc +++ b/model.cc @@ -858,6 +858,54 @@ bool ModelChecker::process_write(ModelAction *curr) return updated_mod_order || updated_promises; } +/** + * Process a fence ModelAction + * @param curr The ModelAction to process + * @return True if synchronization was updated + */ +bool ModelChecker::process_fence(ModelAction *curr) +{ + /* + * fence-relaxed: no-op + * fence-release: only log the occurence (not in this function), for + * use in later synchronization + * fence-acquire (this function): search for hypothetical release + * sequences + */ + bool updated = false; + if (curr->is_acquire()) { + action_list_t *list = action_trace; + action_list_t::reverse_iterator rit; + /* Find X : is_read(X) && X --sb-> curr */ + for (rit = list->rbegin(); rit != list->rend(); rit++) { + ModelAction *act = *rit; + if (act->get_tid() != curr->get_tid()) + continue; + /* Stop at the beginning of the thread */ + if (act->is_thread_start()) + break; + /* Stop once we reach a prior fence-acquire */ + if (act->is_fence() && act->is_acquire()) + break; + if (!act->is_read()) + continue; + /* read-acquire will find its own release sequences */ + if (act->is_acquire()) + continue; + + /* Establish hypothetical release sequences */ + rel_heads_list_t release_heads; + get_release_seq_heads(curr, act, &release_heads); + for (unsigned int i = 0; i < release_heads.size(); i++) + if (!act->synchronize_with(release_heads[i])) + set_bad_synchronization(); + if (release_heads.size() != 0) + updated = true; + } + } + return updated; +} + /** * @brief Process the current action for thread-related activity * @@ -1173,6 +1221,9 @@ Thread * ModelChecker::check_current_action(ModelAction *curr) if (act->is_write() && process_write(act)) update = true; + if (act->is_fence() && process_fence(act)) + update_all = true; + if (act->is_mutex_op() && process_mutex(act)) update_all = true; diff --git a/model.h b/model.h index b078939d..5543eb8a 100644 --- a/model.h +++ b/model.h @@ -152,6 +152,7 @@ private: bool initialize_curr_action(ModelAction **curr); bool process_read(ModelAction *curr, bool second_part_of_rmw); bool process_write(ModelAction *curr); + bool process_fence(ModelAction *curr); bool process_mutex(ModelAction *curr); bool process_thread_action(ModelAction *curr); void process_relseq_fixup(ModelAction *curr, work_queue_t *work_queue);