Lumiera  0.pre.03
»edit your freedom«
sync-locking-test.cpp
Go to the documentation of this file.
1 /*
2  SyncLocking(Test) - check the monitor object based locking
3 
4  Copyright (C)
5  2008, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 * *****************************************************************/
13 
19 #include "lib/test/run.hpp"
20 
21 #include "lib/sync.hpp"
22 #include "lib/thread.hpp"
23 #include "lib/iter-explorer.hpp"
25 
26 using test::Test;
27 using lib::explore;
28 using std::this_thread::yield;
29 using std::this_thread::sleep_for;
30 using std::chrono_literals::operator ""us;
31 
32 
33 namespace lib {
34 namespace test{
35 
36  namespace { // private test classes and data...
37 
38  const uint NUM_THREADS = 200;
39  const uint MAX_RAND_SUMMAND = 100;
40 
41 
42 
44  template<class POLICY>
45  class Checker
46  : public Sync<POLICY>
47  {
48  size_t hot_sum_{0};
49  size_t control_sum_{0};
50 
51  using Lock = typename Sync<POLICY>::Lock;
52 
53  public:
54  bool
55  verify()
56  {
57  Lock guard{this};
58  return 0 < hot_sum_
59  and control_sum_ == hot_sum_;
60  }
61 
62  uint
63  createVal()
64  {
65  uint val = rani (MAX_RAND_SUMMAND);
66  control_sum_ += val;
67  return val;
68  }
69 
70  void
71  addValues (uint a, uint b)
72  {
73  Lock guard{this};
74 
75  hot_sum_ *= 2;
76  sleep_for (200us); // force preemption
77  hot_sum_ += 2 * (a+b);
78  sleep_for (200us);
79  hot_sum_ /= 2;
80  }
81  };
82  }// (End) test classes and data....
83 
84 
85 
86 
87 
88 
89  /******************************************************************/
99  class SyncLocking_test : public Test
100  {
101 
102  virtual void
103  run (Arg)
104  {
105  seedRand();
106  CHECK (can_calc_without_Error<NonrecursiveLock_NoWait>());
107  CHECK (can_calc_without_Error<RecursiveLock_NoWait>());
108  CHECK (not can_calc_without_Error<sync::NoLocking>());
109  }
110 
111 
112  template<class POLICY>
113  bool
114  can_calc_without_Error()
115  {
116  Checker<POLICY> checksum; // shared variable used by multiple threads
117 
118  lib::ScopedCollection<Thread> threads{NUM_THREADS};
119  for (uint i=1; i<=NUM_THREADS; ++i)
120  threads.emplace ([&checksum, // Note: added values prepared in main thread
121  a = checksum.createVal(),
122  b = checksum.createVal()]
123  {
124  checksum.addValues (a,b);
125  });
126 
127  while (explore(threads).has_any())
128  yield(); // wait for all threads to terminate
129 
130  return checksum.verify();
131  }
132  };
133 
134 
135 
137  LAUNCHER (SyncLocking_test, "function common");
138 
139 
140 
141 }} // namespace lib::test
Facility for monitor object based locking.
Definition: sync.hpp:209
A fixed collection of non-copyable polymorphic objects.
Helper to verify a contended chain calculation.
auto explore(IT &&srcSeq)
start building a IterExplorer by suitably wrapping the given iterable source.
Definition: run.hpp:40
int rani(uint bound=_iBOUND())
Definition: random.hpp:135
Implementation namespace for support and library code.
Managing a collection of non-copyable polymorphic objects in compact storage.
Object Monitor based synchronisation.
Abstract Base Class for all testcases.
Definition: run.hpp:53
Simplistic test class runner.
Convenience front-end to simplify and codify basic thread handling.
Building tree expanding and backtracking evaluations within hierarchical scopes.