mc2lib
cats.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2016, Marco Elver
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the
15  * distribution.
16  *
17  * * Neither the name of the software nor the names of its contributors
18  * may be used to endorse or promote products derived from this
19  * software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33 
34 #ifndef MC2LIB_MEMCONSISTENCY_CATS_HPP_
35 #define MC2LIB_MEMCONSISTENCY_CATS_HPP_
36 
37 #include <memory>
38 
39 #include "eventsets.hpp"
40 
41 namespace mc2lib {
42 namespace memconsistency {
43 
58 namespace cats {
59 
60 class ExecWitness {
61  public:
62  template <class FilterFunc>
63  EventRel fr(FilterFunc filter_func) const {
64  EventRel er;
65 
66  // Use of get() is justified, as we do not expect (according to wf_rf), the
67  // rf-relation to have any additional properties.
68  for (const auto& rf_tuples : rf.get()) {
69  const auto co_reach = co.Reachable(rf_tuples.first);
70  for (const auto& co_w : co_reach.get()) {
71  for (const auto& rf_r : rf_tuples.second.get()) {
72  if (filter_func(std::make_pair(rf_tuples.first, rf_r),
73  std::make_pair(rf_tuples.first, co_w))) {
74  er.Insert(rf_r, co_w);
75  }
76  }
77  }
78  }
79 
80  return er;
81  }
82 
83  EventRel fr() const {
84  return fr([](const EventRel::Tuple& t1, const EventRel::Tuple& t2) {
85  return true;
86  });
87  }
88 
89  EventRel fri() const {
90  return fr([](const EventRel::Tuple& t1, const EventRel::Tuple& t2) {
91  return t1.second.iiid.pid == t2.second.iiid.pid;
92  });
93  }
94 
95  EventRel fre() const {
96  return fr([](const EventRel::Tuple& t1, const EventRel::Tuple& t2) {
97  return t1.second.iiid.pid != t2.second.iiid.pid;
98  });
99  }
100 
101  EventRel rfi() const {
102  return rf.Filter([](const Event& e1, const Event& e2) {
103  return e1.iiid.pid == e2.iiid.pid;
104  });
105  }
106 
107  EventRel rfe() const {
108  return rf.Filter([](const Event& e1, const Event& e2) {
109  return e1.iiid.pid != e2.iiid.pid;
110  });
111  }
112 
113  EventRel coi() const {
114  return co.Filter([](const Event& e1, const Event& e2) {
115  return e1.iiid.pid == e2.iiid.pid;
116  });
117  }
118 
119  EventRel coe() const {
120  return co.Filter([](const Event& e1, const Event& e2) {
121  return e1.iiid.pid != e2.iiid.pid;
122  });
123  }
124 
125  EventRel com() const { return rf | co | fr(); }
126 
127  EventRel po_loc() const {
128  return po.Filter(
129  [](const Event& e1, const Event& e2) { return e1.addr == e2.addr; });
130  }
131 
132  void Clear() {
133  events.Clear();
134  po.Clear();
135  co.Clear();
136  rf.Clear();
137  }
138 
139  public:
144 };
145 
146 class Checker;
147 
149  public:
150  Architecture() : proxy_(this) {}
151 
152  virtual ~Architecture() { assert(proxy_ == this); }
153 
154  virtual void Clear() {}
155 
159  virtual std::unique_ptr<Checker> MakeChecker(
160  const Architecture* arch, const ExecWitness* exec) const = 0;
161 
162  virtual EventRel ppo(const ExecWitness& ew) const = 0;
163  virtual EventRel fences(const ExecWitness& ew) const = 0;
164  virtual EventRel prop(const ExecWitness& ew) const = 0;
165 
166  virtual EventRel hb(const ExecWitness& ew) const {
167  return ew.rfe() | proxy_->ppo(ew) | proxy_->fences(ew);
168  }
169 
173  virtual Event::Type EventTypeRead() const = 0;
174 
178  virtual Event::Type EventTypeWrite() const = 0;
179 
180  void set_proxy(const Architecture* proxy) {
181  assert(proxy != nullptr);
182  proxy_ = proxy;
183  }
184 
185  protected:
187 };
188 
189 template <class ConcreteArch>
190 class ArchProxy : public Architecture {
191  public:
192  explicit ArchProxy(ConcreteArch* arch)
193  : arch_(arch),
194  memoized_ppo_(false),
195  memoized_fences_(false),
196  memoized_prop_(false),
197  memoized_hb_(false) {
198  arch_->set_proxy(this);
199  }
200 
201  ~ArchProxy() override { arch_->set_proxy(arch_); }
202 
203  void Clear() override {
204  arch_->Clear();
205  memoized_ppo_ = false;
206  memoized_fences_ = false;
207  memoized_prop_ = false;
208  memoized_hb_ = false;
209  }
210 
211  std::unique_ptr<Checker> MakeChecker(const Architecture* arch,
212  const ExecWitness* exec) const override {
213  return arch_->MakeChecker(arch, exec);
214  }
215 
216  std::unique_ptr<Checker> MakeChecker(const ExecWitness* exec) const {
217  return MakeChecker(this, exec);
218  }
219 
220  void Memoize(const ExecWitness& ew) {
221  // fences and ppo are likely used by hb and prop
222  fences_ = arch_->fences(ew);
223  memoized_fences_ = true;
224 
225  ppo_ = arch_->ppo(ew);
226  memoized_ppo_ = true;
227 
228  hb_ = arch_->hb(ew);
229  memoized_hb_ = true;
230 
231  prop_ = arch_->prop(ew);
232  memoized_prop_ = true;
233  }
234 
235  EventRel ppo(const ExecWitness& ew) const override {
236  return memoized_ppo_ ? ppo_ : arch_->ppo(ew);
237  }
238 
239  EventRel fences(const ExecWitness& ew) const override {
240  return memoized_fences_ ? fences_ : arch_->fences(ew);
241  }
242 
243  EventRel prop(const ExecWitness& ew) const override {
244  return memoized_prop_ ? prop_ : arch_->prop(ew);
245  }
246 
247  EventRel hb(const ExecWitness& ew) const override {
248  return memoized_hb_ ? hb_ : arch_->hb(ew);
249  }
250 
251  Event::Type EventTypeRead() const override { return arch_->EventTypeRead(); }
252 
253  Event::Type EventTypeWrite() const override {
254  return arch_->EventTypeWrite();
255  }
256 
257  protected:
258  ConcreteArch* arch_;
259 
264 
269 };
270 
271 class Checker {
272  public:
273  Checker(const Architecture* arch, const ExecWitness* exec)
274  : arch_(arch), exec_(exec) {}
275 
276  virtual ~Checker() {}
277 
278  virtual void wf_rf() const {
279  EventSet reads;
280 
281  for (const auto& tuples : exec_->rf.get()) {
282  if (!tuples.first.AnyType(arch_->EventTypeWrite())) {
283  throw Error("WF_RF_NOT_FROM_WRITE");
284  }
285 
286  for (const auto& e : tuples.second.get()) {
287  if (!e.AnyType(arch_->EventTypeRead()) || tuples.first.addr != e.addr) {
288  throw Error("WF_RF_NOT_SAME_LOC");
289  }
290 
291  // For every read, there exists only 1 source!
292  if (reads.Contains(e)) {
293  throw Error("WF_RF_MULTI_SOURCE");
294  }
295  reads.Insert(e);
296  }
297  }
298  }
299 
300  virtual void wf_co() const {
301  std::unordered_set<types::Addr> addrs;
302 
303  // Assert writes ordered captured in ws are to the same location.
304  for (const auto& tuples : exec_->co.get()) {
305  addrs.insert(tuples.first.addr);
306 
307  for (const auto& e : tuples.second.get()) {
308  if (tuples.first.addr != e.addr) {
309  throw Error("WF_CO_NOT_SAME_LOC");
310  }
311  }
312  }
313 
314  auto writes = exec_->events.Filter(
315  [&](const Event& e) { return e.AnyType(arch_->EventTypeWrite()); });
316  if (!exec_->co.StrictPartialOrder(writes)) {
317  throw Error("WF_CO_NOT_STRICT_PARTIAL_ORDER");
318  }
319 
320  for (const auto& addr : addrs) {
321  auto same_addr_writes =
322  writes.Filter([&](const Event& e) { return e.addr == addr; });
323  if (!exec_->co.ConnexOn(same_addr_writes)) {
324  throw Error("WF_CO_NOT_CONNEX");
325  }
326  }
327  }
328 
329  virtual void wf() const {
330  wf_rf();
331  wf_co();
332  }
333 
334  virtual bool sc_per_location(EventRel::Path* cyclic = nullptr) const {
335  return (exec_->com() | exec_->po_loc()).Acyclic(cyclic);
336  }
337 
338  virtual bool no_thin_air(EventRel::Path* cyclic = nullptr) const {
339  return arch_->hb(*exec_).Acyclic(cyclic);
340  }
341 
342  virtual bool observation(EventRel::Path* cyclic = nullptr) const {
343  const EventRel prop = arch_->prop(*exec_);
344  const EventRel hbstar =
346 
347  // Not eval'ing hbstar causes performance to degrade substantially, as
348  // EventRelSeq recomputes reachability from nodes from prop to hbstar
349  // several times!
350  bool r = EventRelSeq({exec_->fre(), prop, hbstar.Eval()}).Irreflexive();
351 
352  if (!r && cyclic != nullptr) {
353  // However, here we want hbstar unevald, as otherwise the graph is
354  // too collapsed.
355  EventRelSeq({exec_->fre(), prop, hbstar}).Irreflexive(cyclic);
356  }
357 
358  return r;
359  }
360 
361  virtual bool propagation(EventRel::Path* cyclic = nullptr) const {
362  return (exec_->co | arch_->prop(*exec_)).Acyclic(cyclic);
363  }
364 
365  virtual void valid_exec(EventRel::Path* cyclic = nullptr) const {
366  wf();
367 
368  if (!sc_per_location(cyclic)) {
369  throw Error("SC_PER_LOCATION");
370  }
371 
372  if (!no_thin_air(cyclic)) {
373  throw Error("NO_THIN_AIR");
374  }
375 
376  if (!observation(cyclic)) {
377  throw Error("OBSERVATION");
378  }
379 
380  if (!propagation(cyclic)) {
381  throw Error("PROPAGATION");
382  }
383  }
384 
385  protected:
388 };
389 
390 /*
391 =============================
392 Some common memory models.
393 =============================
394 */
395 
396 class Arch_SC : public Architecture {
397  public:
398  std::unique_ptr<Checker> MakeChecker(const Architecture* arch,
399  const ExecWitness* exec) const override {
400  return std::unique_ptr<Checker>(new Checker(arch, exec));
401  }
402 
403  EventRel ppo(const ExecWitness& ew) const override {
404  assert(ew.po.Transitive());
405  return ew.po.Eval();
406  }
407 
408  EventRel fences(const ExecWitness& ew) const override { return EventRel(); }
409 
410  EventRel prop(const ExecWitness& ew) const override {
411  return proxy_->ppo(ew) | proxy_->fences(ew) | ew.rf | ew.fr();
412  }
413 
414  Event::Type EventTypeRead() const override { return Event::kRead; }
415 
416  Event::Type EventTypeWrite() const override { return Event::kWrite; }
417 };
418 
419 class Arch_TSO : public Architecture {
420  public:
421  void Clear() override { mfence.Clear(); }
422 
423  std::unique_ptr<Checker> MakeChecker(const Architecture* arch,
424  const ExecWitness* exec) const override {
425  return std::unique_ptr<Checker>(new Checker(arch, exec));
426  }
427 
428  EventRel ppo(const ExecWitness& ew) const override {
429  assert(ew.po.Transitive());
430  return ew.po.Filter([](const Event& e1, const Event& e2) {
431  return !e1.AllType(Event::kWrite) || !e2.AllType(Event::kRead);
432  });
433  }
434 
435  EventRel fences(const ExecWitness& ew) const override {
436  if (mfence.empty()) {
437  return mfence;
438  }
439 
440  // Filter postar by only those events which are possibly relevent.
441  const auto postar =
442  ew.po
443  .Filter([&](const Event& e1, const Event& e2) {
444  // Only include those where first event is write or second
445  // is a read, all other are included in po regardless.
446  return e1.AllType(Event::kWrite) || e2.AllType(Event::kRead);
447  })
448  .set_props(EventRel::kReflexiveClosure);
449 
450  return EventRelSeq({postar, mfence, postar}).EvalClear();
451  }
452 
453  EventRel prop(const ExecWitness& ew) const override {
454  return proxy_->ppo(ew) | proxy_->fences(ew) | ew.rfe() | ew.fr();
455  }
456 
457  Event::Type EventTypeRead() const override { return Event::kRead; }
458 
459  Event::Type EventTypeWrite() const override { return Event::kWrite; }
460 
461  public:
463 };
464 
468 class Arch_ARMv7 : public Architecture {
469  public:
470  Arch_ARMv7() { dd_reg.set_props(EventRel::kTransitiveClosure); }
471 
472  void Clear() override {
473  dd_reg.Clear();
474  dsb.Clear();
475  dmb.Clear();
476  dsb_st.Clear();
477  dmb_st.Clear();
478  isb.Clear();
479  }
480 
481  std::unique_ptr<Checker> MakeChecker(const Architecture* arch,
482  const ExecWitness* exec) const override {
483  return std::unique_ptr<Checker>(new Checker(arch, exec));
484  }
485 
486  EventRel ppo(const ExecWitness& ew) const override {
487  assert(ew.po.Transitive());
488  assert(dd_reg.SubsetEq(ew.po));
489 
490  // 1. Obtain dependencies
491  //
492  EventRel addr, data, ctrl_part;
493  dd_reg.for_each(
494  [&addr, &data, &ctrl_part, this](const Event& e1, const Event& e2) {
495  if (!e1.AnyType(EventTypeRead())) {
496  return;
497  }
498 
500  if (e2.AllType(Event::kRegInAddr)) {
501  addr.Insert(e1, e2);
502  }
503 
504  if (e2.AllType(Event::kRegInData)) {
505  data.Insert(e1, e2);
506  }
507  }
508 
509  if (e2.AllType(Event::kBranch)) {
510  ctrl_part.Insert(e1, e2);
511  }
512  });
513 
514  EventRel ctrl = EventRelSeq({ctrl_part, ew.po}).EvalClear();
515  EventRel ctrl_cfence = EventRelSeq({ctrl_part, isb}).EvalClear();
516 
517  // 2. Compute helper relations
518  //
519  const auto po_loc = ew.po_loc();
520  const auto rfe = ew.rfe();
521  EventRel dd = addr | data;
522  EventRel rdw = po_loc & EventRelSeq({ew.fre(), rfe}).EvalClear();
523  EventRel detour = po_loc & EventRelSeq({ew.coe(), rfe}).EvalClear();
524  EventRel addrpo = EventRelSeq({addr, ew.po}).EvalClear();
525 
526  // 3. Compute ppo
527  //
528  // Init
529  EventRel ci = ctrl_cfence | detour;
530  EventRel ii = dd | ew.rfi() | rdw;
531  EventRel cc = dd | ctrl | addrpo | po_loc;
532  EventRel ic;
533 
534  std::size_t total_size = ci.size() + ii.size() + cc.size() + ic.size();
535  std::size_t prev_total_size;
536 
537  // Fix-point computation
538  do {
539  prev_total_size = total_size;
540 
541  ci |=
542  EventRelSeq({ci, ii}).EvalClear() | EventRelSeq({cc, ci}).EvalClear();
543 
544  ii |= ci | EventRelSeq({ic, ci}).EvalClear() |
545  EventRelSeq({ii, ii}).EvalClear();
546 
547  cc |= ci | EventRelSeq({ci, ic}).EvalClear() |
548  EventRelSeq({cc, cc}).EvalClear();
549 
550  ic |= ii | cc | EventRelSeq({ic, cc}).EvalClear() |
551  EventRelSeq({ii, ic}).EvalClear();
552 
553  total_size = ci.size() + ii.size() + cc.size() + ic.size();
554  assert(prev_total_size <= total_size);
555  } while (total_size != prev_total_size);
556 
557  EventRel result = ic.Filter([this](const Event& e1, const Event& e2) {
558  return e1.AnyType(EventTypeRead()) && e2.AnyType(EventTypeWrite());
559  });
560  result |= ii.Filter([this](const Event& e1, const Event& e2) {
561  return e1.AnyType(EventTypeRead()) && e2.AnyType(EventTypeRead());
562  });
563 
564  return result;
565  }
566 
567  // Ensure fences is transitive
568  EventRel fences(const ExecWitness& ew) const override {
569  const auto postar = ew.po.Eval().set_props(EventRel::kReflexiveClosure);
570  const auto postar_WW = postar.Filter([&](const Event& e1, const Event& e2) {
571  return e1.AllType(Event::kWrite) && e2.AllType(Event::kWrite);
572  });
573 
574  auto ff = EventRelSeq({postar, (dmb | dsb), postar}).EvalClear();
575  ff |= EventRelSeq({postar_WW, (dmb_st | dsb_st), postar_WW}).EvalClear();
576  return ff;
577  }
578 
579  EventRel prop(const ExecWitness& ew) const override {
580  EventRel hbstar = proxy_->hb(ew)
582  .EvalInplace();
583  EventRel A_cumul = EventRelSeq({ew.rfe(), proxy_->fences(ew)}).EvalClear();
584  EventRel propbase =
585  EventRelSeq({(proxy_->fences(ew) | A_cumul), hbstar}).EvalClear();
586 
588 
589  EventRel result = propbase.Filter([this](const Event& e1, const Event& e2) {
590  return e1.AnyType(EventTypeWrite()) && e2.AnyType(EventTypeWrite());
591  });
592 
594  result |=
595  EventRelSeq({comstar, propbase /*star*/, proxy_->fences(ew), hbstar})
596  .EvalClear();
597  return result;
598  }
599 
600  Event::Type EventTypeRead() const override { return Event::kRead; }
601 
602  Event::Type EventTypeWrite() const override { return Event::kWrite; }
603 
604  public:
611 };
612 
613 } // namespace cats
614 } // namespace memconsistency
615 } // namespace mc2lib
616 
617 #endif /* MEMCONSISTENCY_CATS_HPP_ */
618 
619 /* vim: set ts=2 sts=2 sw=2 et : */
Definition: eventsets.hpp:227
EventRel ppo_
Definition: cats.hpp:265
void set_proxy(const Architecture *proxy)
Definition: cats.hpp:180
bool AllType(Type type_mask) const
Definition: eventsets.hpp:209
std::unique_ptr< Checker > MakeChecker(const Architecture *arch, const ExecWitness *exec) const override
Definition: cats.hpp:211
EventRel rfe() const
Definition: cats.hpp:107
EventRel ppo(const ExecWitness &ew) const override
Definition: cats.hpp:235
bool AnyType(Type type_mask) const
Definition: eventsets.hpp:213
bool Transitive() const
Definition: sets.hpp:693
EventRel fences(const ExecWitness &ew) const override
Definition: cats.hpp:239
Set< Ts > Reachable(const Element &e) const
Definition: sets.hpp:656
virtual void valid_exec(EventRel::Path *cyclic=nullptr) const
Definition: cats.hpp:365
Event::Type EventTypeRead() const override
Definition: cats.hpp:414
bool memoized_hb_
Definition: cats.hpp:263
~ArchProxy() override
Definition: cats.hpp:201
EventRel ppo(const ExecWitness &ew) const override
Definition: cats.hpp:486
void Clear() override
Definition: cats.hpp:203
Definition: cats.hpp:47
EventRel dmb_st
Definition: cats.hpp:609
EventRel coe() const
Definition: cats.hpp:119
EventRel mfence
Definition: cats.hpp:462
EventRel prop(const ExecWitness &ew) const override
Definition: cats.hpp:579
Event::Type EventTypeRead() const override
Definition: cats.hpp:600
EventRel po_loc() const
Definition: cats.hpp:127
EventRel prop(const ExecWitness &ew) const override
Definition: cats.hpp:410
virtual ~Architecture()
Definition: cats.hpp:152
const Architecture * proxy_
Definition: cats.hpp:186
EventRel po
Definition: cats.hpp:141
EventRel fr() const
Definition: cats.hpp:83
EventRel fences(const ExecWitness &ew) const override
Definition: cats.hpp:435
const Element & Insert(const Element &e, bool assert_unique=false)
Definition: sets.hpp:112
Event::Type EventTypeWrite() const override
Definition: cats.hpp:416
std::uint32_t Type
Definition: eventsets.hpp:111
Iiid iiid
Definition: eventsets.hpp:220
std::vector< Element > Path
Definition: sets.hpp:327
virtual ~Checker()
Definition: cats.hpp:276
EventRel dsb_st
Definition: cats.hpp:608
std::pair< Element, Element > Tuple
Definition: sets.hpp:325
virtual bool sc_per_location(EventRel::Path *cyclic=nullptr) const
Definition: cats.hpp:334
const ExecWitness * exec_
Definition: cats.hpp:387
virtual bool propagation(EventRel::Path *cyclic=nullptr) const
Definition: cats.hpp:361
EventRel isb
Definition: cats.hpp:610
void Clear()
Definition: cats.hpp:132
EventRel fences(const ExecWitness &ew) const override
Definition: cats.hpp:408
Event::Type EventTypeWrite() const override
Definition: cats.hpp:602
Definition: eventsets.hpp:103
virtual void wf_rf() const
Definition: cats.hpp:278
sets::RelationSeq< sets::Types< Event > > EventRelSeq
Definition: eventsets.hpp:225
std::size_t size() const
Definition: sets.hpp:434
Func for_each(Func func) const
Definition: sets.hpp:457
Relation & EvalInplace()
Definition: sets.hpp:494
EventRel fri() const
Definition: cats.hpp:89
EventRel dmb
Definition: cats.hpp:607
static constexpr Properties kReflexiveClosure
Definition: sets.hpp:341
static constexpr Type kBranch
Definition: eventsets.hpp:128
void Clear()
Definition: sets.hpp:156
EventRel prop_
Definition: cats.hpp:267
bool Contains(const Element &e) const
Definition: sets.hpp:158
Relation Eval() const
Definition: sets.hpp:475
std::unique_ptr< Checker > MakeChecker(const ExecWitness *exec) const
Definition: cats.hpp:216
EventRel prop(const ExecWitness &ew) const override
Definition: cats.hpp:243
std::unique_ptr< Checker > MakeChecker(const Architecture *arch, const ExecWitness *exec) const override
Definition: cats.hpp:398
std::unique_ptr< Checker > MakeChecker(const Architecture *arch, const ExecWitness *exec) const override
Definition: cats.hpp:423
EventRel coi() const
Definition: cats.hpp:113
EventRel dsb
Definition: cats.hpp:606
EventSet events
Definition: cats.hpp:140
static constexpr Type kMemoryOperation
Definition: eventsets.hpp:122
virtual void wf_co() const
Definition: cats.hpp:300
const Container & get() const
Definition: sets.hpp:355
Arch_ARMv7()
Definition: cats.hpp:470
EventRel fences_
Definition: cats.hpp:266
Event::Type EventTypeRead() const override
Definition: cats.hpp:251
EventRel fre() const
Definition: cats.hpp:95
sets::Relation< sets::Types< Event > > EventRel
Definition: eventsets.hpp:224
static constexpr Type kRegInAddr
Definition: eventsets.hpp:125
EventRel rfi() const
Definition: cats.hpp:101
EventRel dd_reg
Definition: cats.hpp:605
Event::Type EventTypeRead() const override
Definition: cats.hpp:457
static constexpr Properties kReflexiveTransitiveClosure
Definition: sets.hpp:342
EventRel ppo(const ExecWitness &ew) const override
Definition: cats.hpp:428
bool memoized_ppo_
Definition: cats.hpp:260
EventRel prop(const ExecWitness &ew) const override
Definition: cats.hpp:453
types::Addr addr
Definition: eventsets.hpp:218
EventRel rf
Definition: cats.hpp:143
void Clear() override
Definition: cats.hpp:472
Relation Filter(FilterFunc filterFunc) const
Definition: sets.hpp:511
void Memoize(const ExecWitness &ew)
Definition: cats.hpp:220
void Insert(const Element &e1, const Element &e2, bool assert_unique=false)
Definition: sets.hpp:384
EventRel ppo(const ExecWitness &ew) const override
Definition: cats.hpp:403
static constexpr Type kRead
Definition: eventsets.hpp:118
ArchProxy(ConcreteArch *arch)
Definition: cats.hpp:192
bool memoized_fences_
Definition: cats.hpp:261
EventRel co
Definition: cats.hpp:142
void Clear() override
Definition: cats.hpp:421
static constexpr Type kWrite
Definition: eventsets.hpp:119
Architecture()
Definition: cats.hpp:150
bool memoized_prop_
Definition: cats.hpp:262
EventRel fences(const ExecWitness &ew) const override
Definition: cats.hpp:568
EventRel hb(const ExecWitness &ew) const override
Definition: cats.hpp:247
types::Pid pid
Definition: eventsets.hpp:99
EventRel hb_
Definition: cats.hpp:268
ConcreteArch * arch_
Definition: cats.hpp:258
static constexpr Properties kTransitiveClosure
Definition: sets.hpp:340
virtual void wf() const
Definition: cats.hpp:329
virtual EventRel hb(const ExecWitness &ew) const
Definition: cats.hpp:166
Checker(const Architecture *arch, const ExecWitness *exec)
Definition: cats.hpp:273
Event::Type EventTypeWrite() const override
Definition: cats.hpp:253
const Architecture * arch_
Definition: cats.hpp:386
EventRel fr(FilterFunc filter_func) const
Definition: cats.hpp:63
static constexpr Type kRegInData
Definition: eventsets.hpp:126
std::unique_ptr< Checker > MakeChecker(const Architecture *arch, const ExecWitness *exec) const override
Definition: cats.hpp:481
virtual bool no_thin_air(EventRel::Path *cyclic=nullptr) const
Definition: cats.hpp:338
EventRel com() const
Definition: cats.hpp:125
Event::Type EventTypeWrite() const override
Definition: cats.hpp:459
virtual void Clear()
Definition: cats.hpp:154
void Clear()
Definition: sets.hpp:596
virtual bool observation(EventRel::Path *cyclic=nullptr) const
Definition: cats.hpp:342
Relation & set_props(Properties props)
Definition: sets.hpp:359