Lumiera  0.pre.03
»edit your freedom«
typed-counter.hpp
Go to the documentation of this file.
1 /*
2  TYPED-COUNTER.hpp - maintain a set of type based contexts
3 
4  Copyright (C) Lumiera.org
5  2009, 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 
23 
59 #ifndef LIB_TYPED_COUNTER_H
60 #define LIB_TYPED_COUNTER_H
61 
62 #include "lib/error.hpp"
63 #include "lib/sync-classlock.hpp"
64 
65 #include <atomic>
66 #include <string>
67 #include <deque>
68 
69 
70 namespace util {
71  std::string showSize (size_t) noexcept;
72 }
73 
74 namespace lib {
75 
76  typedef size_t IxID;
77 
78  using std::deque;
79  using std::string;
80 
81 
94  template<class CX>
96  {
97  static IxID lastGeneratedTypeID;
98 
99  public:
100  static IxID
101  newTypeID (IxID& typeID)
102  {
103  ClassLock<TypedContext> synchronised;
104  if (!typeID)
105  typeID = ++lastGeneratedTypeID;
106  return typeID;
107  }
108 
110  template<typename TY>
111  class ID
112  {
113  static IxID typeID;
114 
115  public:
116  static IxID
117  get()
118  {
119  if (typeID)
120  return typeID;
121  else
122  return newTypeID(typeID);
123  }
124  };
125  };
126 
128  template<class CX>
130 
132  template<class CX>
133  template<typename TY>
135 
136 
137 
138 
149  : public Sync<>
150  {
151  mutable deque<std::atomic_int64_t> counters_;
152 
153  template<typename TY>
154  IxID
155  slot() const
156  {
158  if (size() < typeID)
159  { // protect against concurrent slot allocations
160  Lock sync{this};
161  if (size() < typeID)
162  counters_.resize (typeID);
163  }
164 
165  ENSURE (counters_.size() >= typeID);
166  return (typeID - 1);
167  }
168 
169 
170  public:
171  template<class X>
172  int64_t
173  get() const
174  {
175  return counters_[slot<X>()].load(std::memory_order_relaxed);
176  }
177 
178  template<class X>
179  int64_t
180  inc()
181  { // yields the value seen previously
182  return 1 + counters_[slot<X>()].fetch_add(+1, std::memory_order_relaxed);
183  }
184 
185  template<class X>
186  int64_t
187  dec()
188  {
189  return -1 + counters_[slot<X>()].fetch_add(-1, std::memory_order_relaxed);
190  }
191 
192 
193  /* == diagnostics == */
194 
195  size_t size() const { return counters_.size(); }
196  bool empty() const { return counters_.empty();}
197  };
198 
199 
200 
211  template<typename TY>
213  {
214  const size_t id_;
215 
217  static std::atomic_size_t memberCounter;
218 
220  static size_t
222  { // Note : returning previous value before increment
223  return memberCounter.fetch_add(+1, std::memory_order_relaxed);
224  }
225 
226  public:
227  FamilyMember()
228  : id_{allocateNextMember()}
229  { }
230 
231  operator size_t() const
232  {
233  return id_;
234  }
235 
236  operator string() const
237  {
238  return util::showSize (this->id_);
239  }
240 
241  friend string
242  operator+ (string const& prefix, FamilyMember id)
243  {
244  return prefix+string(id);
245  }
246 
247  friend string
248  operator+ (const char* prefix, FamilyMember id)
249  {
250  return string(prefix)+id;
251  }
252  };
253 
255  template<typename TY>
256  std::atomic_size_t FamilyMember<TY>::memberCounter{0};
257 
258 
259 
260 } // namespace lib
261 #endif
Facility for monitor object based locking.
Definition: sync.hpp:217
Utility providing a set of counters, each tied to a specific type.
static IxID lastGeneratedTypeID
storage for the type-ID generation mechanism
Implementation namespace for support and library code.
static size_t allocateNextMember()
threadsafe allocation of member ID
std::string operator+(std::string str, Literal const &sym)
string concatenation
Definition: symbol.hpp:222
static std::atomic_size_t memberCounter
member counter shared per template instance
A special implementation of lib::Sync, where the storage of the object monitor is associated directly...
Lumiera error handling (C++ interface).
A synchronisation protection guard employing a lock scoped to the parameter type as a whole...
Utility to produce member IDs for objects belonging to a "Family", as defined by a distinguishing typ...
static IxID typeID
table holding all the generated type-IDs
Provide type-IDs for a specific context.