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) Lumiera.org
5  2008, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
28 #include "lib/test/run.hpp"
29 
30 #include "lib/sync.hpp"
31 #include "lib/thread.hpp"
32 #include "lib/iter-explorer.hpp"
34 
35 using test::Test;
36 using lib::explore;
37 using std::this_thread::yield;
38 using std::this_thread::sleep_for;
39 using std::chrono_literals::operator ""us;
40 
41 
42 namespace lib {
43 namespace test{
44 
45  namespace { // private test classes and data...
46 
47  const uint NUM_THREADS = 200;
48  const uint MAX_RAND_SUMMAND = 100;
49 
50 
51 
53  template<class POLICY>
54  class Checker
55  : public Sync<POLICY>
56  {
57  size_t hot_sum_{0};
58  size_t control_sum_{0};
59 
60  using Lock = typename Sync<POLICY>::Lock;
61 
62  public:
63  bool
64  verify()
65  {
66  Lock guard{this};
67  return 0 < hot_sum_
68  and control_sum_ == hot_sum_;
69  }
70 
71  uint
72  createVal()
73  {
74  uint val{rand() % MAX_RAND_SUMMAND};
75  control_sum_ += val;
76  return val;
77  }
78 
79  void
80  addValues (uint a, uint b)
81  {
82  Lock guard{this};
83 
84  hot_sum_ *= 2;
85  sleep_for (200us); // force preemption
86  hot_sum_ += 2 * (a+b);
87  sleep_for (200us);
88  hot_sum_ /= 2;
89  }
90  };
91  }// (End) test classes and data....
92 
93 
94 
95 
96 
97 
98  /******************************************************************/
108  class SyncLocking_test : public Test
109  {
110 
111  virtual void
112  run (Arg)
113  {
114  CHECK (can_calc_without_Error<NonrecursiveLock_NoWait>());
115  CHECK (can_calc_without_Error<RecursiveLock_NoWait>());
116  CHECK (not can_calc_without_Error<sync::NoLocking>());
117  }
118 
119 
120  template<class POLICY>
121  bool
122  can_calc_without_Error()
123  {
124  Checker<POLICY> checksum; // shared variable used by multiple threads
125 
126  lib::ScopedCollection<Thread> threads{NUM_THREADS};
127  for (uint i=1; i<=NUM_THREADS; ++i)
128  threads.emplace ([&checksum, // Note: added values prepared in main thread
129  a = checksum.createVal(),
130  b = checksum.createVal()]
131  {
132  checksum.addValues (a,b);
133  });
134 
135  while (explore(threads).has_any())
136  yield(); // wait for all threads to terminate
137 
138  return checksum.verify();
139  }
140  };
141 
142 
143 
145  LAUNCHER (SyncLocking_test, "function common");
146 
147 
148 
149 }} // namespace lib::test
Facility for monitor object based locking.
Definition: sync.hpp:217
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:49
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:62
Simple test class runner.
Convenience front-end to simplify and codify basic thread handling.
Building tree expanding and backtracking evaluations within hierarchical scopes.