CBMC
shared_buffers.h
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module:
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
9 
10 #ifndef CPROVER_GOTO_INSTRUMENT_WMM_SHARED_BUFFERS_H
11 #define CPROVER_GOTO_INSTRUMENT_WMM_SHARED_BUFFERS_H
12 
13 #include <util/cprover_prefix.h>
14 #include <util/namespace.h>
15 #include <util/symbol_table_base.h>
16 
18 
19 #include "wmm.h"
20 
21 #include <map>
22 #include <set>
23 
24 class goto_functionst;
25 class messaget;
26 class value_setst;
27 
29 {
30 public:
32  symbol_table_baset &_symbol_table,
33  unsigned _nb_threads,
34  messaget &_message)
35  : symbol_table(_symbol_table),
36  nb_threads(_nb_threads + 1),
37  uniq(0),
38  cav11(false),
39  message(_message)
40  {
41  }
42 
44  {
45  if(model!=TSO)
46  throw "sorry, CAV11 only available for TSO";
47  cav11 = true;
48  }
49 
50  /* instrumentation of a variable */
51  class varst
52  {
53  public:
54  // Older stuff has the higher index.
55  // Shared buffer.
57 
58  // Are those places empty?
60 
61  // Delays write buffer flush: just to make some swaps between mem and buff
62  // -- this is to model lhs := rhs with rhs reading in the buffer without
63  // affecting the memory (Note: we model lhs := rhs by rhs := ..., then
64  // lhs := rhs)
67 
68  // Thread: Was it me who wrote at this place?
69  std::vector<irep_idt> r_buff0_thds, r_buff1_thds;
70 
71  // for delayed read:
74 
76  };
77 
78  typedef std::map<irep_idt, varst> var_mapt;
80 
81  /* instructions in violation cycles (to instrument): */
82  // variables in the cycles
83  std::set<irep_idt> cycles;
84  // events instrumented: var->locations in the code
85  std::multimap<irep_idt, source_locationt> cycles_loc;
86  // events in cycles: var->locations (for read instrumentations)
87  std::multimap<irep_idt, source_locationt> cycles_r_loc;
88 
89  const varst &operator()(const irep_idt &object);
90 
91  void add_initialization_code(goto_functionst &goto_functions);
92 
93  void delay_read(
94  goto_programt &goto_program,
96  const source_locationt &source_location,
97  const irep_idt &read_object,
98  const irep_idt &write_object);
99 
100  void flush_read(
101  goto_programt &goto_program,
103  const source_locationt &source_location,
104  const irep_idt &write_object);
105 
106  void write(
107  goto_programt &goto_program,
109  const source_locationt &source_location,
110  const irep_idt &object,
111  goto_programt::instructiont &original_instruction,
112  const unsigned current_thread);
113 
114  void det_flush(
115  goto_programt &goto_program,
117  const source_locationt &source_location,
118  const irep_idt &object,
119  const unsigned current_thread);
120 
121  void nondet_flush(
122  const irep_idt &function_id,
123  goto_programt &goto_program,
125  const source_locationt &source_location,
126  const irep_idt &object,
127  const unsigned current_thread,
128  const bool tso_pso_rmo);
129 
130  void assignment(
131  goto_programt &goto_program,
133  const source_locationt &source_location,
134  const irep_idt &id_lhs,
135  const exprt &rhs);
136 
138  goto_programt &goto_program,
140  const source_locationt &source_location,
141  const irep_idt &id_lhs,
142  const irep_idt &id_rhs)
143  {
145  assignment(goto_program, t, source_location, id_lhs,
146  ns.lookup(id_rhs).symbol_expr());
147  }
148 
149  bool track(const irep_idt &id) const
150  {
152 
153  const symbolt &symbol=ns.lookup(id);
154  if(symbol.is_thread_local)
155  return false;
156  if(id.starts_with(CPROVER_PREFIX))
157  return false;
158 
159  return true;
160  }
161 
162  irep_idt choice(const irep_idt &function_id, const std::string &suffix)
163  {
164  const auto maybe_symbol = symbol_table.lookup(function_id);
165  CHECK_RETURN(maybe_symbol);
166  return add(*maybe_symbol, "_weak_choice" + suffix, bool_typet());
167  }
168 
169  bool is_buffered(
170  const namespacet&,
171  const symbol_exprt&,
172  bool is_write);
173 
175  const symbol_exprt&,
176  bool is_write);
177 
179  value_setst &value_sets,
181  goto_programt &goto_program,
182  memory_modelt model,
183  goto_functionst &goto_functions);
184 
185  void affected_by_delay(
186  value_setst &value_sets,
187  goto_functionst &goto_functions);
188 
190  {
191  protected:
195 
196  /* for thread marking (dynamic) */
197  unsigned current_thread;
198  unsigned coming_from;
199  unsigned max_thread;
200 
201  /* data propagated through the CFG */
202  std::set<irep_idt> past_writes;
203 
204  public:
206  shared_bufferst &_shared,
207  symbol_table_baset &_symbol_table,
208  goto_functionst &_goto_functions)
209  : shared_buffers(_shared),
210  symbol_table(_symbol_table),
211  goto_functions(_goto_functions)
212  {
213  current_thread = 0;
214  coming_from = 0;
215  max_thread = 0;
216  }
217 
218  void weak_memory(
219  value_setst &value_sets,
220  const irep_idt &function_id,
221  memory_modelt model);
222  };
223 
224 protected:
226 
227  // number of threads interfering
228  unsigned nb_threads;
229 
230  // instrumentations (not to be instrumented again)
231  std::set<irep_idt> instrumentations;
232 
233  // variables (non necessarily shared) affected by reads delay
234 public:
235  std::set<irep_idt> affected_by_delay_set;
236 
237 protected:
238  // for fresh variables
239  unsigned uniq;
240 
241  std::string unique();
242 
243  bool cav11;
244 
245  /* message */
247 
248  irep_idt add(
249  const symbolt &object,
250  const std::string &suffix,
251  const typet &type,
252  bool added_as_instrumentation);
253 
254  irep_idt
255  add(const symbolt &object, const std::string &suffix, const typet &type)
256  {
257  return add(object, suffix, type, true);
258  }
259 
260  /* inserting a non-instrumenting, fresh variable */
262  const symbolt &object,
263  const std::string &suffix,
264  const typet &type)
265  {
266  return add(object, suffix, type, false);
267  }
268 
269  void add_initialization(goto_programt &goto_program);
270 };
271 
272 #endif // CPROVER_GOTO_INSTRUMENT_WMM_SHARED_BUFFERS_H
The Boolean type.
Definition: std_types.h:36
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
A collection of goto functions.
This class represents an instruction in the GOTO intermediate representation.
Definition: goto_program.h:181
A generic container class for the GOTO intermediate representation of one function.
Definition: goto_program.h:73
instructionst::iterator targett
Definition: goto_program.h:614
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:94
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
Definition: namespace.cpp:148
shared_bufferst & shared_buffers
symbol_table_baset & symbol_table
void weak_memory(value_setst &value_sets, const irep_idt &function_id, memory_modelt model)
instruments the program for the pairs detected through the CFG
cfg_visitort(shared_bufferst &_shared, symbol_table_baset &_symbol_table, goto_functionst &_goto_functions)
std::set< irep_idt > past_writes
goto_functionst & goto_functions
std::vector< irep_idt > r_buff0_thds
std::vector< irep_idt > r_buff1_thds
std::multimap< irep_idt, source_locationt > cycles_loc
const varst & operator()(const irep_idt &object)
instruments the variable
void set_cav11(memory_modelt model)
void nondet_flush(const irep_idt &function_id, goto_programt &goto_program, goto_programt::targett &t, const source_locationt &source_location, const irep_idt &object, const unsigned current_thread, const bool tso_pso_rmo)
instruments read
std::string unique()
returns a unique id (for fresh variables)
void write(goto_programt &goto_program, goto_programt::targett &t, const source_locationt &source_location, const irep_idt &object, goto_programt::instructiont &original_instruction, const unsigned current_thread)
instruments write
void weak_memory(value_setst &value_sets, symbol_table_baset &symbol_table, goto_programt &goto_program, memory_modelt model, goto_functionst &goto_functions)
void affected_by_delay(value_setst &value_sets, goto_functionst &goto_functions)
analysis over the goto-program which computes in affected_by_delay_set the variables (non necessarily...
shared_bufferst(symbol_table_baset &_symbol_table, unsigned _nb_threads, messaget &_message)
void det_flush(goto_programt &goto_program, goto_programt::targett &t, const source_locationt &source_location, const irep_idt &object, const unsigned current_thread)
flush buffers (instruments fence)
irep_idt add_fresh_var(const symbolt &object, const std::string &suffix, const typet &type)
void add_initialization(goto_programt &goto_program)
bool is_buffered_in_general(const symbol_exprt &, bool is_write)
void assignment(goto_programt &goto_program, goto_programt::targett &t, const source_locationt &source_location, const irep_idt &id_lhs, const exprt &rhs)
add an assignment in the goto-program
irep_idt add(const symbolt &object, const std::string &suffix, const typet &type, bool added_as_instrumentation)
add a new var for instrumenting the input var
std::set< irep_idt > affected_by_delay_set
class symbol_table_baset & symbol_table
std::set< irep_idt > cycles
void delay_read(goto_programt &goto_program, goto_programt::targett &t, const source_locationt &source_location, const irep_idt &read_object, const irep_idt &write_object)
delays a read (POWER)
void flush_read(goto_programt &goto_program, goto_programt::targett &t, const source_locationt &source_location, const irep_idt &write_object)
flushes read (POWER)
std::multimap< irep_idt, source_locationt > cycles_r_loc
messaget & message
std::map< irep_idt, varst > var_mapt
irep_idt choice(const irep_idt &function_id, const std::string &suffix)
void add_initialization_code(goto_functionst &goto_functions)
bool track(const irep_idt &id) const
irep_idt add(const symbolt &object, const std::string &suffix, const typet &type)
bool is_buffered(const namespacet &, const symbol_exprt &, bool is_write)
std::set< irep_idt > instrumentations
void assignment(goto_programt &goto_program, goto_programt::targett &t, const source_locationt &source_location, const irep_idt &id_lhs, const irep_idt &id_rhs)
Expression to hold a symbol (variable)
Definition: std_expr.h:131
The symbol table base class interface.
const symbolt * lookup(const irep_idt &name) const
Find a symbol in the symbol table for read-only access.
Symbol table entry.
Definition: symbol.h:28
bool is_thread_local
Definition: symbol.h:71
The type of an expression, extends irept.
Definition: type.h:29
#define CPROVER_PREFIX
Concrete Goto Program.
#define CHECK_RETURN(CONDITION)
Definition: invariant.h:495
Author: Diffblue Ltd.
memory models
memory_modelt
Definition: wmm.h:18
@ TSO
Definition: wmm.h:20