CBMC
memory_model_tso.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Memory model for partial order concurrency
4 
5 Author: Michael Tautschnig, michael.tautschnig@cs.ox.ac.uk
6 
7 \*******************************************************************/
8 
11 
12 #include "memory_model_tso.h"
13 
14 #include <util/std_expr.h>
15 #include <util/simplify_expr.h>
16 
18 operator()(symex_target_equationt &equation, message_handlert &message_handler)
19 {
20  messaget log{message_handler};
21  log.statistics() << "Adding TSO constraints" << messaget::eom;
22 
23  build_event_lists(equation, message_handler);
25 
26  read_from(equation);
28  program_order(equation);
29 #ifndef CPROVER_MEMORY_MODEL_SUP_CLOCK
30  from_read(equation);
31 #endif
32 }
33 
35 {
38 }
39 
43 {
44  PRECONDITION(e1->is_shared_read() || e1->is_shared_write());
45  PRECONDITION(e2->is_shared_read() || e2->is_shared_write());
46 
47  // no po relaxation within atomic sections
48  if(e1->atomic_section_id!=0 &&
49  e1->atomic_section_id==e2->atomic_section_id)
50  return false;
51 
52  // write to read program order is relaxed
53  return e1->is_shared_write() && e2->is_shared_read();
54 }
55 
57  symex_target_equationt &equation)
58 {
59  per_thread_mapt per_thread_map;
60  build_per_thread_map(equation, per_thread_map);
61 
62  thread_spawn(equation, per_thread_map);
63 
64  // iterate over threads
65 
66  for(per_thread_mapt::const_iterator
67  t_it=per_thread_map.begin();
68  t_it!=per_thread_map.end();
69  t_it++)
70  {
71  const event_listt &events=t_it->second;
72 
73  // iterate over relevant events in the thread
74 
75  for(event_listt::const_iterator
76  e_it=events.begin();
77  e_it!=events.end();
78  e_it++)
79  {
80  if((*e_it)->is_memory_barrier())
81  continue;
82 
83  event_listt::const_iterator next=e_it;
84  ++next;
85 
86  exprt mb_guard_r = false_exprt();
87  exprt mb_guard_w = false_exprt();
88 
89  for(event_listt::const_iterator
90  e_it2=next;
91  e_it2!=events.end();
92  e_it2++)
93  {
94  if(((*e_it)->is_spawn() && !(*e_it2)->is_memory_barrier()) ||
95  (*e_it2)->is_spawn())
96  {
98  equation,
99  before(*e_it, *e_it2),
100  "po",
101  (*e_it)->source);
102 
103  if((*e_it2)->is_spawn())
104  break;
105  else
106  continue;
107  }
108 
109  if((*e_it2)->is_memory_barrier())
110  {
111  const codet &code = (*e_it2)->source.pc->code();
112 
113  if((*e_it)->is_shared_read() &&
114  !code.get_bool(ID_RRfence) &&
115  !code.get_bool(ID_RWfence))
116  continue;
117  else if((*e_it)->is_shared_write() &&
118  !code.get_bool(ID_WRfence) &&
119  !code.get_bool(ID_WWfence))
120  continue;
121 
122  if(code.get_bool(ID_RRfence) ||
123  code.get_bool(ID_WRfence))
124  mb_guard_r=or_exprt(mb_guard_r, (*e_it2)->guard);
125 
126  if(code.get_bool(ID_RWfence) ||
127  code.get_bool(ID_WWfence))
128  mb_guard_w=or_exprt(mb_guard_w, (*e_it2)->guard);
129 
130  continue;
131  }
132 
133  exprt cond=true_exprt();
134  exprt ordering=nil_exprt();
135 
136  if(address(*e_it)==address(*e_it2))
137  {
139  *e_it, *e_it2, AX_SC_PER_LOCATION);
140  }
141  else if(program_order_is_relaxed(*e_it, *e_it2))
142  {
143  if((*e_it2)->is_shared_read())
144  cond=mb_guard_r;
145  else
146  cond=mb_guard_w;
147 
148  simplify(cond, ns);
149  }
150 
151  if(!cond.is_false())
152  {
153  if(ordering.is_nil())
155  *e_it, *e_it2, AX_PROPAGATION);
156 
158  equation,
159  implies_exprt(cond, ordering),
160  "po",
161  (*e_it)->source);
162  }
163  }
164  }
165  }
166 }
Data structure for representing an arbitrary statement in a program.
Definition: std_code_base.h:29
Base class for all expressions.
Definition: expr.h:56
bool is_false() const
Return whether the expression is a constant representing false.
Definition: expr.cpp:34
The Boolean constant false.
Definition: std_expr.h:3064
Boolean implication.
Definition: std_expr.h:2183
bool get_bool(const irep_idt &name) const
Definition: irep.cpp:57
bool is_nil() const
Definition: irep.h:364
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...
std::map< unsigned, event_listt > per_thread_mapt
Definition: memory_model.h:60
void build_per_thread_map(const symex_target_equationt &equation, per_thread_mapt &dest) const
void from_read(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)
virtual void operator()(symex_target_equationt &equation, message_handlert &)
void program_order(symex_target_equationt &equation)
virtual bool program_order_is_relaxed(partial_order_concurrencyt::event_it e1, partial_order_concurrencyt::event_it e2) const
Class that provides messages with a built-in verbosity 'level'.
Definition: message.h:155
static eomt eom
Definition: message.h:297
The NIL expression.
Definition: std_expr.h:3073
Boolean OR.
Definition: std_expr.h:2228
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...
irep_idt address(event_it event) const
Produce an address ID for an event.
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
Inheriting the interface of symex_targett this class represents the SSA form of the input program as ...
The Boolean constant true.
Definition: std_expr.h:3055
double log(double x)
Definition: math.c:2776
Memory models for partial order concurrency.
bool simplify(exprt &expr, const namespacet &ns)
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
API to expression classes.