CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
partial_order_concurrency.h
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Add constraints to equation encoding partial orders on events
4
5Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk
6
7\*******************************************************************/
8
11
12#ifndef CPROVER_GOTO_SYMEX_PARTIAL_ORDER_CONCURRENCY_H
13#define CPROVER_GOTO_SYMEX_PARTIAL_ORDER_CONCURRENCY_H
14
16
21{
22public:
25
28 typedef eventst::const_iterator event_it;
29
30 // the name of a clock variable for a shared read/write
38
43 static irep_idt rw_clock_id(
44 event_it e,
46
47protected:
48 const namespacet &ns;
49
50 typedef std::vector<event_it> event_listt;
51
52 // lists of reads and writes per address
53 struct a_rect
54 {
56 };
57
58 typedef std::map<irep_idt, a_rect> address_mapt;
60
70 symex_target_equationt &equation,
71 message_handlert &message_handler);
72
78
79 // a per-thread numbering of the events
80 typedef std::map<event_it, unsigned> numberingt;
82
86 static inline irep_idt id(event_it event)
87 {
88 return event->ssa_lhs.get_identifier();
89 }
90
95 {
96 return remove_level_2(event->ssa_lhs).get_identifier();
97 }
98
100
106
108 void build_clock_type();
109
115 void add_constraint(
116 symex_target_equationt &equation,
117 const exprt &cond,
118 const std::string &msg,
119 const symex_targett::sourcet &source) const;
120
129 exprt before(event_it e1, event_it e2, unsigned axioms);
131};
132
133#if 0
134#include <list>
135#include <map>
136#include <vector>
137#include <string>
138
139#include "abstract_event_structure.h"
140
142
143class numbered_evtst
144{
145 typedef abstract_eventt evtt;
146
147public:
148 typedef std::vector<evtt const*> ordered_evtst;
149 // NOLINTNEXTLINE(readability/identifiers)
150 typedef ordered_evtst::const_iterator const_iterator;
151 typedef std::map<evtt const*, ordered_evtst::size_type> ordered_evts_mapt;
152
153 void add_event(const evtt &evt)
154 {
155 const ordered_evtst::size_type offset=ordered_evts.size();
156 ordered_evts.push_back(&evt);
157 if(!ordered_evts_map.insert(std::make_pair(&evt, offset)).second)
159 assert(ordered_evts.size()==ordered_evts_map.size());
160
161 if(evt.direction==evtt::D_SYNC ||
162 evt.direction==evtt::D_LWSYNC)
163 barriers.insert(barriers.end(), offset);
164 }
165
166 void add_events(const_iterator first, const_iterator last)
167 {
168 ordered_evts.reserve(ordered_evts.size()+last-first);
169 for( ; first!=last; ++first)
170 add_event(**first);
171 }
172
173 const_iterator begin() const
174 {
175 return ordered_evts.begin();
176 }
177
178 const_iterator end() const
179 {
180 return ordered_evts.end();
181 }
182
183 const_iterator find(const evtt &evt) const
184 {
185 ordered_evts_mapt::const_iterator entry=ordered_evts_map.find(&evt);
186 if(entry==ordered_evts_map.end())
187 return end();
188
189 return ordered_evts.begin()+entry->second;
190 }
191
192 std::list<const_iterator> barriers_after(const evtt &evt) const
193 {
194 const_iterator entry=find(evt);
195 if(entry==end())
196 return std::list<const_iterator>();
197
198 std::list<const_iterator> ret;
199 ordered_evtst::size_type offset=entry-begin();
200 for(std::set<ordered_evtst::size_type>::const_iterator
201 lb=barriers.lower_bound(offset);
202 lb!=barriers.end();
203 ++lb)
204 ret.push_back(ordered_evts.begin()+*lb);
205
206 return ret;
207 }
208
209 std::list<const_iterator> barriers_before(const evtt &evt) const
210 {
211 const_iterator entry=find(evt);
212 if(entry==end())
213 return std::list<const_iterator>();
214
215 std::list<const_iterator> ret;
216 ordered_evtst::size_type offset=entry-begin();
217 for(std::set<ordered_evtst::size_type>::const_iterator
218 ub=barriers.begin();
219 ub!=barriers.end() && *ub<=offset;
220 ++ub)
221 ret.push_back(ordered_evts.begin()+*ub);
222
223 return ret;
224 }
225
226private:
229 std::set<ordered_evtst::size_type> barriers;
230};
231
233{
234public:
235 // the is-acyclic checks
236 enum acyclict
237 {
238 AC_UNIPROC=0,
239 AC_THINAIR=1,
240 AC_GHB=2,
243 };
244
245 typedef abstract_eventt evtt;
246 typedef std::map<evtt const*, std::map<evtt const*, exprt> > adj_matrixt;
248 typedef std::list<evtt const*> per_valuet;
249 typedef std::map<irep_idt, per_valuet> per_address_mapt;
250 typedef std::vector<numbered_evtst> numbered_per_thread_evtst;
251
255 const namespacet &_ns,
257
259 void add_atomic_sections();
260
261 // collect all partial orders
265 void add_from_read(
266 const adj_matricest &rf,
267 const adj_matricest &ws,
269 void add_barriers(
270 const adj_matricest &po,
271 const adj_matricest &rf,
272 const adj_matricest &fr);
273
274 void acyclic();
275
276 // steps as used in PLDI Power model
277# define S_COMMIT 0
278# define S_R_REQ 1
279# define S_S_ACK 1
280# define S_PROP(t) ((t+1)<<1)
282 const acyclict check,
283 const evtt &n,
284 const unsigned step) const;
286 const acyclict check,
287 const evtt &n,
288 const unsigned step,
289 const evtt::event_dirt other_dir) const;
290
292 void add_constraint(
293 exprt &expr,
294 const guardt &guard,
295 const symex_targett::sourcet &source,
296 const std::string &po_name);
297 void add_atomic_sections(const acyclict check);
299 const acyclict check,
300 const std::string &po_name,
301 const evtt &n1,
302 const evtt &n2,
303 const exprt &cond);
305 const acyclict check,
306 const std::string &po_name,
307 const evtt &n1,
308 const unsigned n1_step,
310 const evtt &n2,
311 const unsigned n2_step,
313 const exprt &cond);
314
315 const evtt* first_of(const evtt &e1, const evtt &e2) const;
316 const numbered_evtst &get_thread(const evtt &e) const;
318 {
319 return per_thread_evt_no;
320 }
321
322 const namespacet &get_ns() const { return ns; }
323 messaget &get_message() { return message; }
324 std::map<std::string, unsigned> num_concurrency_constraints;
325
326private:
327 memory_model_baset &memory_model;
329 const namespacet &ns;
330 messaget &message;
331
332 // collect all reads and writes to each address
334
335 // initialisation events for uninitialised globals
336 std::map<irep_idt, evtt> init_val;
337
338 // constraints added to the formula
339 const std::string prop_var;
340 unsigned prop_cnt;
341
342 // number events according to po per thread, including parents
344
345 // map between events and (symbolic) integers
347 std::map<evtt const*, unsigned> barrier_id;
349 const evtt &evt,
350 const std::string &prefix) const;
351 std::vector<std::pair<symbol_exprt, symbol_exprt>>
353
354 std::list<exprt> acyclic_constraints[AC_N_AXIOMS];
355 static std::string check_to_string(const acyclict check);
356
357 // map point-wise order to a single Boolean symbol
358 typedef std::pair<evtt const*, std::pair<unsigned, evtt::event_dirt>>
360 typedef std::map<std::pair<evt_dir_pairt, evt_dir_pairt>,
363 typedef std::map<evtt const*,
364 std::list<std::pair<evtt const*, std::pair<exprt, std::string> > > >
367
368 void add_sub_clock_rules();
369
370 typedef std::map<std::pair<irep_idt, irep_idt>, symbol_exprt> clock_mapt;
373 const symbol_exprt &n1_sym,
374 const symbol_exprt &n2_sym,
375 const symex_targett::sourcet &source,
376 const std::string &po_name);
378 const acyclict check,
379 const std::string &po_name,
380 const evtt &n1,
381 const unsigned n1_step,
383 const evtt &n2,
384 const unsigned n2_step,
387 const acyclict check,
388 const std::string &po_name,
389 const evtt &n1,
390 const unsigned n1_step,
392 const evtt &n2,
393 const unsigned n2_step,
395 symbol_exprt &dest);
396
397 // debugging output
398 std::string event_to_string(const evtt &evt) const;
399 void print_graph(
400 const adj_matrixt &graph,
401 const std::string &edge_label,
402 namespacet const &ns) const;
403};
404#endif
405
406#endif // CPROVER_GOTO_SYMEX_PARTIAL_ORDER_CONCURRENCY_H
static exprt guard(const exprt::operandst &guards, exprt cond)
Single SSA step in the equation.
Definition ssa_step.h:47
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
ait()
Definition ai.h:565
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:38
Base class for all expressions.
Definition expr.h:56
Class that provides messages with a built-in verbosity 'level'.
Definition message.h:154
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition namespace.h:91
Base class for implementing memory models via additional constraints for SSA equations.
std::vector< event_it > event_listt
void add_init_writes(symex_target_equationt &)
For each shared read event and for each shared write event that appears after spawn or has false guar...
std::map< event_it, unsigned > numberingt
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...
irep_idt address(event_it event) const
Produce an address ID for an event.
symbol_exprt clock(event_it e, axiomt axiom)
Produce a clock symbol for some event.
virtual exprt before(event_it e1, event_it e2)=0
void build_clock_type()
Initialize the clock_type so that it can be used to number events.
std::map< irep_idt, a_rect > address_mapt
static irep_idt rw_clock_id(event_it e, axiomt axiom=AX_PROPAGATION)
Build identifier for the read/write clock variable.
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.
symex_target_equationt::SSA_stepst eventst
static irep_idt id(event_it event)
Produce the symbol ID for an event.
Expression to hold a symbol (variable)
Definition std_expr.h:131
const irep_idt & get_identifier() const
Definition std_expr.h:160
Inheriting the interface of symex_targett this class represents the SSA form of the input program as ...
std::list< SSA_stept > SSA_stepst
The type of an expression, extends irept.
Definition type.h:29
#define UNREACHABLE
This should be used to mark dead code.
Definition invariant.h:525
ssa_exprt remove_level_2(ssa_exprt ssa)
Definition ssa_expr.cpp:219
Identifies source in the context of symbolic execution.
Generate Equation using Symbolic Execution.