CBMC
Loading...
Searching...
No Matches
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 || e_it->is_shared_read() || e_it->guard != true)
55 {
56 init_steps.emplace_back(
58 SSA_stept &SSA_step = init_steps.back();
59
60 SSA_step.guard=true_exprt();
61 // no SSA L2 index, thus nondet value
62 SSA_step.ssa_lhs = remove_level_2(e_it->ssa_lhs);
63 SSA_step.atomic_section_id=0;
64 }
65
66 init_done.insert(a);
67 }
68
69 equation.SSA_steps.splice(equation.SSA_steps.begin(), init_steps);
70}
71
73 symex_target_equationt &equation,
74 message_handlert &message_handler)
75{
76 add_init_writes(equation);
77
78 // a per-thread counter
79 std::map<unsigned, unsigned> counter;
80
81 for(eventst::const_iterator
82 e_it=equation.SSA_steps.begin();
83 e_it!=equation.SSA_steps.end();
84 e_it++)
85 {
86 if(e_it->is_shared_read() ||
87 e_it->is_shared_write() ||
88 e_it->is_spawn())
89 {
90 unsigned thread_nr=e_it->source.thread_nr;
91
92 if(!e_it->is_spawn())
93 {
95
96 if(e_it->is_shared_read())
97 a_rec.reads.push_back(e_it);
98 else // must be write
99 a_rec.writes.push_back(e_it);
100 }
101
102 // maps an event id to a per-thread counter
103 unsigned cnt=counter[thread_nr]++;
105 }
106 }
107
108 messaget log{message_handler};
109 for(address_mapt::const_iterator
110 a_it=address_map.begin();
111 a_it!=address_map.end();
112 a_it++)
113 {
114 const a_rect &a_rec=a_it->second;
115 if(a_rec.reads.empty())
116 continue;
117
118 log.statistics() << "Shared " << a_it->first << ": " << a_rec.reads.size()
119 << "R/" << a_rec.writes.size() << "W" << messaget::eom;
120 }
121}
122
126{
127 if(event->is_shared_write())
128 return id2string(id(event))+"$wclk$"+std::to_string(axiom);
129 else if(event->is_shared_read())
130 return id2string(id(event))+"$rclk$"+std::to_string(axiom);
131 else
133}
134
138{
139 PRECONDITION(!numbering.empty());
140 irep_idt identifier;
141
142 if(event->is_shared_write())
143 identifier=rw_clock_id(event, axiom);
144 else if(event->is_shared_read())
145 identifier=rw_clock_id(event, axiom);
146 else if(event->is_spawn())
147 {
148 identifier=
149 "t"+std::to_string(event->source.thread_nr+1)+"$"+
150 std::to_string(numbering[event])+"$spwnclk$"+std::to_string(axiom);
151 }
152 else
154
155 return symbol_exprt(identifier, clock_type);
156}
157
159{
160 PRECONDITION(!numbering.empty());
161
162 std::size_t width = address_bits(numbering.size());
164}
165
167 event_it e1, event_it e2, unsigned axioms)
168{
169 const axiomt axiom_bits[]=
170 {
175 };
176
178 ops.reserve(sizeof(axiom_bits)/sizeof(axiomt));
179
180 for(int i=0; i<int(sizeof(axiom_bits)/sizeof(axiomt)); ++i)
181 {
182 const axiomt ax=axiom_bits[i];
183
184 if((axioms &ax)==0)
185 continue;
186
187 if(e1->atomic_section_id!=0 &&
188 e1->atomic_section_id==e2->atomic_section_id)
189 ops.push_back(equal_exprt(clock(e1, ax), clock(e2, ax)));
190 else
191 ops.push_back(
193 }
194
195 POSTCONDITION(!ops.empty());
196
197 return conjunction(ops);
198}
199
201 symex_target_equationt &equation,
202 const exprt &cond,
203 const std::string &msg,
204 const symex_targett::sourcet &source) const
205{
206 exprt tmp=cond;
207 simplify(tmp, ns);
208
209 equation.constraint(tmp, msg, source);
210}
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:57
std::vector< exprt > operandst
Definition expr.h:59
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:3237
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(exprt a, exprt b)
Conjunction of two expressions.
Definition std_expr.cpp:252
Identifies source in the context of symbolic execution.