1/*******************************************************************\
3Module: Memory model for partial order concurrency
5Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk
7\*******************************************************************/
51 // this orders the events within a thread
53 for(eventst::const_iterator
58 // concurrency-related?
59 if(!
e_it->is_shared_read() &&
60 !
e_it->is_shared_write() &&
62 !
e_it->is_memory_barrier())
continue;
64 dest[
e_it->source.thread_nr].push_back(
e_it);
72 // thread spawn: the spawn precedes the first
73 // instruction of the new thread in program order
76 for(eventst::const_iterator
88 // add a constraint for all events,
89 // considering regression/cbmc-concurrency/pthread_create_tso1
90 for(event_listt::const_iterator
95 if(!(*n_it)->is_memory_barrier())
111 // thread spawn: the spawn precedes the first
112 // instruction of the new thread in program order
115 for(eventst::const_iterator
127 // For SC and several weaker memory models a memory barrier
128 // at the beginning of a thread can simply be ignored, because
129 // we enforce program order in the thread-spawn constraint
130 // anyway. Memory models with cumulative memory barriers
131 // require explicit handling of these.
135 (*n_it)->is_memory_barrier();
159 // iterate over threads
161 for(per_thread_mapt::const_iterator
168 // iterate over relevant events in the thread
172 for(event_listt::const_iterator
177 if((*e_it)->is_memory_barrier())
201 for(address_mapt::const_iterator
208 // This is quadratic in the number of writes
209 // per address. Perhaps some better encoding
210 // based on 'places'?
211 for(event_listt::const_iterator
216 event_listt::const_iterator next=
w_it1;
219 for(event_listt::const_iterator
w_it2=next;
224 if((*w_it1)->source.thread_nr==
225 (*w_it2)->source.thread_nr)
228 // ws is a total order, no two elements have the same rank
229 // s -> w_evt1 before w_evt2; !s -> w_evt2 before w_evt1
233 // write-to-write edge
252 // from-read: (w', w) in ws and (w', r) in rf -> (r, w) in fr
254 for(address_mapt::const_iterator
261 // This is quadratic in the number of writes per address.
262 for(event_listt::const_iterator
267 event_listt::const_iterator next=
w_prime;
270 for(event_listt::const_iterator
w=next;
295 for(choice_symbolst::const_iterator
309 // the guard of w_prime follows from rf; with rfi
310 // optimisation such as the previous write_symbol_primed
311 // it would even be wrong to add this guard
317 else if(
c_it->first.second == *
w &&
ws2 !=
false)
321 // the guard of w follows from rf; with rfi
322 // optimisation such as the previous write_symbol_primed
323 // it would even be wrong to add this guard
332 cond,
"fr",
r->source);
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Boolean AND All operands must be boolean, and the result is always boolean.
Base class for all expressions.
The Boolean constant false.
symbol_exprt nondet_bool_symbol(const std::string &prefix)
bool po(event_it e1, event_it e2)
In-thread program order.
void read_from(symex_target_equationt &equation)
For each read r from every address we collect the choice symbols S via register_read_from_choice_symb...
choice_symbolst choice_symbols
std::map< unsigned, event_listt > per_thread_mapt
virtual void operator()(symex_target_equationt &equation, message_handlert &)
void build_per_thread_map(const symex_target_equationt &equation, per_thread_mapt &dest) const
void from_read(symex_target_equationt &equation)
virtual bool program_order_is_relaxed(partial_order_concurrencyt::event_it e1, partial_order_concurrencyt::event_it e2) const
void program_order(symex_target_equationt &equation)
void thread_spawn(symex_target_equationt &equation, const per_thread_mapt &per_thread_map)
void write_serialization_external(symex_target_equationt &equation)
virtual exprt before(event_it e1, event_it e2)
Class that provides messages with a built-in verbosity 'level'.
std::vector< event_it > event_listt
void build_event_lists(symex_target_equationt &equation, message_handlert &message_handler)
First call add_init_writes then for each shared read/write (or spawn) populate: 1) the address_map (w...
exprt before(event_it e1, event_it e2, unsigned axioms)
Build the partial order constraint for two events: if e1 and e2 are in the same atomic section then c...
void build_clock_type()
Initialize the clock_type so that it can be used to number events.
void add_constraint(symex_target_equationt &equation, const exprt &cond, const std::string &msg, const symex_targett::sourcet &source) const
Simplify and add a constraint to equation.
eventst::const_iterator event_it
Expression to hold a symbol (variable)
Inheriting the interface of symex_targett this class represents the SSA form of the input program as ...
The Boolean constant true.
const std::string next_thread_id
Memory models for partial order concurrency.
#define PRECONDITION(CONDITION)
API to expression classes.