CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
partial_order_concurrency.cpp
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
13
14#include <util/arith_tools.h>
16#include <util/simplify_expr.h>
17
22
26
28 symex_target_equationt &equation)
29{
30 std::unordered_set<irep_idt> init_done;
31 bool spawn_seen=false;
32
34
35 for(eventst::const_iterator
36 e_it=equation.SSA_steps.begin();
37 e_it!=equation.SSA_steps.end();
38 e_it++)
39 {
40 if(e_it->is_spawn())
41 {
42 spawn_seen=true;
43 continue;
44 }
45 else if(!e_it->is_shared_read() &&
46 !e_it->is_shared_write())
47 continue;
48
49 const irep_idt &a=address(e_it);
50
51 if(init_done.find(a)!=init_done.end())
52 continue;
53
54 if(spawn_seen ||
55 e_it->is_shared_read() ||
56 !e_it->guard.is_true())
57 {
58 init_steps.emplace_back(
60 SSA_stept &SSA_step = init_steps.back();
61
62 SSA_step.guard=true_exprt();
63 // no SSA L2 index, thus nondet value
64 SSA_step.ssa_lhs = remove_level_2(e_it->ssa_lhs);
65 SSA_step.atomic_section_id=0;
66 }
67
68 init_done.insert(a);
69 }
70
71 equation.SSA_steps.splice(equation.SSA_steps.begin(), init_steps);
72}
73
75 symex_target_equationt &equation,
76 message_handlert &message_handler)
77{
78 add_init_writes(equation);
79
80 // a per-thread counter
81 std::map<unsigned, unsigned> counter;
82
83 for(eventst::const_iterator
84 e_it=equation.SSA_steps.begin();
85 e_it!=equation.SSA_steps.end();
86 e_it++)
87 {
88 if(e_it->is_shared_read() ||
89 e_it->is_shared_write() ||
90 e_it->is_spawn())
91 {
92 unsigned thread_nr=e_it->source.thread_nr;
93
94 if(!e_it->is_spawn())
95 {
97
98 if(e_it->is_shared_read())
99 a_rec.reads.push_back(e_it);
100 else // must be write
101 a_rec.writes.push_back(e_it);
102 }
103
104 // maps an event id to a per-thread counter
105 unsigned cnt=counter[thread_nr]++;
107 }
108 }
109
110 messaget log{message_handler};
111 for(address_mapt::const_iterator
112 a_it=address_map.begin();
113 a_it!=address_map.end();
114 a_it++)
115 {
116 const a_rect &a_rec=a_it->second;
117 if(a_rec.reads.empty())
118 continue;
119
120 log.statistics() << "Shared " << a_it->first << ": " << a_rec.reads.size()
121 << "R/" << a_rec.writes.size() << "W" << messaget::eom;
122 }
123}
124
128{
129 if(event->is_shared_write())
130 return id2string(id(event))+"$wclk$"+std::to_string(axiom);
131 else if(event->is_shared_read())
132 return id2string(id(event))+"$rclk$"+std::to_string(axiom);
133 else
135}
136
140{
141 PRECONDITION(!numbering.empty());
142 irep_idt identifier;
143
144 if(event->is_shared_write())
145 identifier=rw_clock_id(event, axiom);
146 else if(event->is_shared_read())
147 identifier=rw_clock_id(event, axiom);
148 else if(event->is_spawn())
149 {
150 identifier=
151 "t"+std::to_string(event->source.thread_nr+1)+"$"+
152 std::to_string(numbering[event])+"$spwnclk$"+std::to_string(axiom);
153 }
154 else
156
157 return symbol_exprt(identifier, clock_type);
158}
159
161{
162 PRECONDITION(!numbering.empty());
163
164 std::size_t width = address_bits(numbering.size());
166}
167
169 event_it e1, event_it e2, unsigned axioms)
170{
171 const axiomt axiom_bits[]=
172 {
177 };
178
180 ops.reserve(sizeof(axiom_bits)/sizeof(axiomt));
181
182 for(int i=0; i<int(sizeof(axiom_bits)/sizeof(axiomt)); ++i)
183 {
184 const axiomt ax=axiom_bits[i];
185
186 if((axioms &ax)==0)
187 continue;
188
189 if(e1->atomic_section_id!=0 &&
190 e1->atomic_section_id==e2->atomic_section_id)
191 ops.push_back(equal_exprt(clock(e1, ax), clock(e2, ax)));
192 else
193 ops.push_back(
195 }
196
197 POSTCONDITION(!ops.empty());
198
199 return conjunction(ops);
200}
201
203 symex_target_equationt &equation,
204 const exprt &cond,
205 const std::string &msg,
206 const symex_targett::sourcet &source) const
207{
208 exprt tmp=cond;
209 simplify(tmp, ns);
210
211 equation.constraint(tmp, msg, source);
212}
std::size_t address_bits(const mp_integer &size)
ceil(log2(size))
Pre-defined bitvector types.
Single SSA step in the equation.
Definition ssa_step.h:47
unsigned atomic_section_id
Definition ssa_step.h:169
exprt guard
Definition ssa_step.h:135
ssa_exprt ssa_lhs
Definition ssa_step.h:139
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
A base class for relations, i.e., binary predicates whose two operands have the same type.
Definition std_expr.h:762
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:38
Equality.
Definition std_expr.h:1366
Base class for all expressions.
Definition expr.h:56
std::vector< exprt > operandst
Definition expr.h:58
Class that provides messages with a built-in verbosity 'level'.
Definition message.h:154
static eomt eom
Definition message.h:289
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition namespace.h:91
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...
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.
void build_clock_type()
Initialize the clock_type so that it can be used to number events.
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.
partial_order_concurrencyt(const namespacet &_ns)
Expression to hold a symbol (variable)
Definition std_expr.h:131
Inheriting the interface of symex_targett this class represents the SSA form of the input program as ...
virtual void constraint(const exprt &cond, const std::string &msg, const sourcet &source)
Record a global constraint: there is no guard limiting its scope.
std::list< SSA_stept > SSA_stepst
The Boolean constant true.
Definition std_expr.h:3190
Fixed-width bit-vector with unsigned binary interpretation.
const std::string & id2string(const irep_idt &d)
Definition irep.h:44
double log(double x)
Definition math.c:2449
Add constraints to equation encoding partial orders on events.
bool simplify(exprt &expr, const namespacet &ns)
#define UNREACHABLE
This should be used to mark dead code.
Definition invariant.h:525
#define PRECONDITION(CONDITION)
Definition invariant.h:463
#define POSTCONDITION(CONDITION)
Definition invariant.h:479
ssa_exprt remove_level_2(ssa_exprt ssa)
Definition ssa_expr.cpp:219
exprt conjunction(const exprt::operandst &op)
1) generates a conjunction for two or more operands 2) for one operand, returns the operand 3) return...
Definition std_expr.cpp:83
Identifies source in the context of symbolic execution.