Geant4  v4-10.4-release
 모두 클래스 네임스페이스들 파일들 함수 변수 타입정의 열거형 타입 열거형 멤버 Friends 매크로 그룹들 페이지들
G4Cache.hh
이 파일의 문서화 페이지로 가기
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 // $Id$
27 //
28 // ---------------------------------------------------------------
29 // GEANT 4 class header file
30 //
31 // Class Description:
32 // Helper classes for Geant4 Multi-Threaded.
33 // The classes defined in this header file provide a thread-private
34 // cache to store, in a class instance shared among threads,
35 // a thread-local variable V.
36 // These are templated classes on the to-be-stored object.
37 //
38 // Example:
39 // Let's assume an instance myObject of class G4Shared is sharead between
40 // threads. Still a data member of this class needs to be thread-private.
41 // A typical example of this being a "cache" for a local calculation.
42 // The helper here defined can be used to guarantee thread-safe operations
43 // on the thread-private object.
44 // Example:
45 // class G4Shared {
46 // G4double sharedData;
47 // G4Cache<G4double> threadPrivate;
48 // void foo() {
49 // G4double priv = threadPrivate.Get();
50 // if ( priv < 10 ) priv += sharedData;
51 // threadPrivate.Put( priv );
52 // }
53 // };
54 //
55 // Two variants of the base G4Cache exists. The first one being
56 // G4VectorCache similar to std::vector
57 // Example:
58 // G4VectorCache<G4double> aVect;
59 // aVect.Push_back( 3.2 );
60 // aVect.Push_back( 4.1 );
61 // cout<<aVect[0]<<endl;
62 // The second one being:
63 // G4MapCache similar to std::map
64 // Example:
65 // G4MapCache<G4int,G4double> aMap;
66 // aMap[320]=1.234;
67 //
68 // See classes definition for details.
69 // See testG4Cache unit test for details on usage
70 //
71 // History:
72 // 21 October 2013: A. Dotti - First implementation
73 
74 #ifndef G4CACHE_HH
75 #define G4CACHE_HH
76 
77 //Debug this code
78 //#define g4cdebug 1
79 
80 #include <system_error>
81 #include <atomic>
82 
83 // also included in G4CacheDetails.hh
84 #include "G4Threading.hh"
85 #include "G4AutoLock.hh"
86 
87 //Thread Local storage details are in this header file
88 #include "G4CacheDetails.hh"
89 
90 // A templated cache to store a thread-private data of type VALTYPE.
91 template<class VALTYPE>
92 class G4Cache {
93 public:
94  typedef VALTYPE value_type;
95  // The stored type
96 
97  G4Cache();
98  // Default constructor
99 
100  G4Cache(const value_type& v);
101  // Construct cache object with initial value
102 
103  virtual ~G4Cache();
104  // Default destructor
105 
106  inline value_type& Get() const;
107  // Gets reference to cached value of this threads
108 
109  inline void Put( const value_type& val ) const;
110  // Sets this thread cached value to val
111 
112  inline value_type Pop();
113  // Gets copy of cached value
114 
115  G4Cache(const G4Cache& rhs);
116  G4Cache& operator=(const G4Cache& rhs);
117 
118 protected:
119  const int& GetId() const { return id; }
120 
121 private:
122  int id;
124  static std::atomic<unsigned int> instancesctr;
125  static std::atomic<unsigned int> dstrctr;
126 
127  inline value_type& GetCache() const {
128  theCache.Initialize(id);
129  return theCache.GetCache(id);
130  }
131 
132 };
133 
134 
135 // A vector version of the cache. Implements vector interface.
136 // Can be used directly as a std::vector would be used.
137 template<class VALTYPE>
138 class G4VectorCache : public G4Cache< std::vector<VALTYPE> > {
139 public:
140  //Some useful defintions
141  typedef VALTYPE value_type;
142  typedef typename std::vector<value_type> vector_type;
143  typedef typename vector_type::size_type size_type;
144  typedef typename vector_type::iterator iterator;
145  typedef typename vector_type::const_iterator const_iterator;
146 
147  G4VectorCache();
148  // Default constructor
149 
150  G4VectorCache( G4int nElems );
151  // Creates a vector cache of nElems elements
152 
153  G4VectorCache( G4int nElems , value_type* vals );
154  // Creates a vector cache with elements from an array
155 
156  virtual ~G4VectorCache();
157  // Default destructor
158 
159  // Interface with funxtionalities of similar name of std::vector
160  inline void Push_back( const value_type& val );
161  inline value_type Pop_back();
162  inline value_type& operator[](const G4int& idx);
163  inline iterator Begin();
164  inline iterator End();
165  inline void Clear();
166  inline size_type Size() { return G4Cache<vector_type>::Get().size(); } //Needs to be here for a VC9 compilation problem
167 };
168 
169 
170 // a Map version of the cache. Implemetns std::map interface.
171 // Can be used directly as a std::map would be used.
172 // KEYTYPE being the key type and VALTYPE the value type.
173 #include <map>
174 template<class KEYTYPE, class VALTYPE>
175 class G4MapCache : public G4Cache<std::map<KEYTYPE,VALTYPE> > {
176 public:
177  //Some useful definitions
178  typedef KEYTYPE key_type;
179  typedef VALTYPE value_type;
180  typedef typename std::map<key_type,value_type> map_type;
181  typedef typename map_type::size_type size_type;
182  typedef typename map_type::iterator iterator;
183  typedef typename map_type::const_iterator const_iterator;
184 
185  virtual ~G4MapCache();
186  // Default destructor
187 
188  inline G4bool Has(const key_type& k );
189  // Returns true if map contains element corresponding to key k
190 
191  // Interface with functionalities of similar name of std::map
192  inline std::pair<iterator,G4bool> Insert( const key_type& k , const value_type& v );
193  inline iterator Begin();
194  inline iterator End();
195  inline iterator Find(const key_type& k );
196  inline value_type& Get(const key_type& k );
197  inline size_type Erase(const key_type& k );
198  inline value_type& operator[](const key_type& k);
199  inline size_type Size() { return G4Cache<map_type>::Get().size(); } //Needs to be here for a VC9 compilation problem
200 };
201 
202 
203 
204 //=============================================================
205 // Implementation details follow
206 //=============================================================
207 
208 
209 
210 #ifdef g4cdebug
211 #include <iostream>
212 #include <sstream>
213 using std::cout;
214 using std::endl;
215 #endif
216 
217 #include "G4AutoLock.hh"
218 
219 
220 //========= Implementation: G4Cache<V>
221 
222 template<class V>
224 {
226  id = instancesctr++;
227 #ifdef g4cdebug
228  cout<<"G4Cache id: "<<id<<endl;
229 #endif
230 }
231 
232 template<class V>
234 {
235  //Copy is special, we need to copy the content
236  //of the cache, not the cache object
237  if ( this == &rhs ) return;
239  id = instancesctr++;
240  //Force copy of cached data
241  V aCopy = rhs.GetCache();
242  Put( aCopy );
243 #ifdef g4cdebug
244  cout<<"Copy constructor with id: "<<id<<endl;
245 #endif
246 }
247 
248 template<class V>
250 {
251  if (this == &rhs) return *this;
252  //Force copy of cached data
253  V aCopy = rhs.GetCache();
254  Put(aCopy);
255 #ifdef g4cdebug
256  cout<<"Assignement operator with id: "<<id<<endl;
257 #endif
258  return *this;
259 }
260 
261 template<class V>
262 G4Cache<V>::G4Cache(const V& v)
263 {
265  id = instancesctr++;
266  Put(v);
267 #ifdef g4cdebug
268  cout<<"G4Cache id: "<<id<<" "<<endl;
269 #endif
270 }
271 
272 template<class V>
274 { //Move base calss
275 #ifdef g4cdebug
276  cout<<"~G4Cache id: "<<id<<" "<<endl;
277 #endif
278  // don't automatically lock --> wait until we can catch an error
279  // without scoping the G4AutoLock
280  G4AutoLock l(G4TypeMutex<G4Cache<V>>(), std::defer_lock);
281  // sometimes the mutex is unavailable in destructors so
282  // try to lock the associated mutex, but catch if fails
283  try
284  {
285  // a system_error in lock means that the mutex is unavailable
286  // we want to throw the error that comes from locking an unavailable
287  // mutex so that we know there is a memory leak
288  // if the mutex is valid, this will hold until the other thread finishes
289  l.lock();
290  }
291  catch (std::system_error& e)
292  {
293  // the error that comes from locking an unavailable mutex
294 #ifdef G4VERBOSE
295  G4cout << "Non-critical error: mutex lock failure in ~G4Cache<"
296  << typeid(V).name() << ">. "
297  << "If the RunManagerKernel has been deleted, it failed to "
298  << "delete an allocated resource and this destructor is being "
299  << "called after the statics were destroyed." << G4endl;
300  G4cout << "Exception: [code: " << e.code() << "] caught: "
301  << e.what() << G4endl;
302 #endif
303  }
304  ++dstrctr;
305  G4bool last = ( dstrctr == instancesctr );
306  theCache.Destroy(id, last);
307  if (last) {
308  instancesctr.store(0);
309  dstrctr.store(0);
310  }
311 }
312 
313 template<class V>
314 V& G4Cache<V>::Get() const
315 { return GetCache(); }
316 
317 template<class V>
318 void G4Cache<V>::Put( const V& val ) const
319 { GetCache() = val; }
320 
321 //Should here remove from cache element?
322 template<class V>
324 { return GetCache(); }
325 
326 template<class V>
327 std::atomic<unsigned int> G4Cache<V>::instancesctr(0);
328 
329 template<class V>
330 std::atomic<unsigned int> G4Cache<V>::dstrctr(0);
331 
332 //========== Implementation: G4VectorCache<V>
333 template<class V>
335 { }
336 
337 template<class V>
339 #ifdef g4cdebug
340  cout<<"~G4VectorCache "<<G4Cache<G4VectorCache<V>::vector_type>::GetId()<<" with size: "<<Size()<<"->";
341  for ( size_type i = 0 ; i < Size() ; ++i )
342  cout<<operator[](i)<<",";
343  cout<<"<-"<<endl;
344 #endif
345 }
346 
347 template<class V>
350  cc.resize(nElems);
351 }
352 
353 template<class V>
354 G4VectorCache<V>::G4VectorCache(G4int nElems , V* vals ) {
355  vector_type& cc = G4Cache<vector_type>::Get();
356  cc.resize(nElems);
357  for ( G4int idx = 0 ; idx < nElems ; ++idx )
358  cc[idx]=vals[idx];
359 }
360 
361 template<class V>
362 void G4VectorCache<V>::Push_back( const V& val )
363 {
364  G4Cache<vector_type>::Get().push_back( val );
365 }
366 
367 template<class V>
369 {
371  value_type val = cc[cc.size()-1];
372  cc.pop_back();
373  return val;
374 }
375 
376 template<class V>
378 {
380  return cc[idx];
381 }
382 
383 template<class V>
385 {
386  return G4Cache<vector_type>::Get().begin();
387 }
388 
389 template<class V>
391 {
392  return G4Cache<vector_type>::Get().end();
393 }
394 
395 template<class V>
397 {
398  G4Cache<vector_type>::Get().clear();
399 }
400 
401 //template<class V>
402 //typename G4VectorCache<V>::size_type G4VectorCache<V>::Size()
403 //{
404 // return G4Cache<vector_type>::Get().size();
405 //}
406 
407 //======== Implementation: G4MapType<K,V>
408 template<class K, class V>
410 {
411 #ifdef g4cdebug
412  cout<<"~G4MacCache "<<G4Cache<map_type>::GetId()<<" with size: "<<Size()<<"->";
413  for ( iterator it = Begin() ; it != End() ; ++it )
414  cout<<it->first<<":"<<it->second<<",";
415  cout<<"<-"<<endl;
416 #endif
417 }
418 
419 template<class K, class V>
420 std::pair<typename G4MapCache<K,V>::iterator,G4bool>
421 G4MapCache<K,V>::Insert(const K& k, const V& v)
422 {
423  return G4Cache<map_type>::Get().insert( std::pair<key_type,value_type>(k,v) );
424 }
425 
426 //template<class K, class V>
427 //typename G4MapCache<K,V>::size_type G4MapCache<K,V>::Size()
428 //{
429 // return G4Cache<map_type>::Get().size();
430 //}
431 
432 template<class K, class V>
434 {
435  return G4Cache<map_type>::Get().begin();
436 }
437 template<class K, class V>
439 {
440  return G4Cache<map_type>::Get().end();
441 }
442 
443 template<class K, class V>
445 {
446  return G4Cache<map_type>::Get().find(k);
447 }
448 
449 template<class K, class V>
451 {
452  return ( Find(k) != End() );
453 }
454 
455 template<class K, class V>
456 V& G4MapCache<K,V>::Get(const K& k )
457 {
458  return Find(k)->second;
459 }
460 
461 template<class K, class V>
463 {
464  return G4Cache<map_type>::Get().erase(k);
465 }
466 
467 template<class K, class V>
469 {
470  return (G4Cache<map_type>::Get())[k];
471 }
472 
473 #endif
const XML_Char * name
Definition: expat.h:151
void Initialize(unsigned int id)
G4CacheReference< value_type > theCache
Definition: G4Cache.hh:123
value_type & operator[](const key_type &k)
Definition: G4Cache.hh:468
vector_type::const_iterator const_iterator
Definition: G4Cache.hh:145
std::pair< iterator, G4bool > Insert(const key_type &k, const value_type &v)
Definition: G4Cache.hh:421
G4Cache & operator=(const G4Cache &rhs)
Definition: G4Cache.hh:249
std::vector< value_type > vector_type
Definition: G4Cache.hh:142
map_type::size_type size_type
Definition: G4Cache.hh:181
#define G4endl
Definition: G4ios.hh:61
G4Cache()
Definition: G4Cache.hh:223
G4bool Has(const key_type &k)
Definition: G4Cache.hh:450
value_type & operator[](const G4int &idx)
Definition: G4Cache.hh:377
value_type Pop_back()
Definition: G4Cache.hh:368
virtual ~G4Cache()
Definition: G4Cache.hh:273
iterator End()
Definition: G4Cache.hh:390
iterator Begin()
Definition: G4Cache.hh:433
G4Mutex & G4TypeMutex(const unsigned int &_n=0)
Definition: G4Threading.hh:114
size_type Erase(const key_type &k)
Definition: G4Cache.hh:462
Double_t K
VALTYPE value_type
Definition: G4Cache.hh:141
value_type & GetCache() const
Definition: G4Cache.hh:127
VALTYPE & GetCache(unsigned int id) const
static std::atomic< unsigned int > dstrctr
Definition: G4Cache.hh:125
value_type Pop()
Definition: G4Cache.hh:323
bool G4bool
Definition: G4Types.hh:79
VALTYPE value_type
Definition: G4Cache.hh:94
VALTYPE value_type
Definition: G4Cache.hh:179
vector_type::iterator iterator
Definition: G4Cache.hh:144
map_type::iterator iterator
Definition: G4Cache.hh:182
virtual ~G4MapCache()
Definition: G4Cache.hh:409
size_type Size()
Definition: G4Cache.hh:199
value_type & Get() const
Definition: G4Cache.hh:314
const int & GetId() const
Definition: G4Cache.hh:119
vector_type::size_type size_type
Definition: G4Cache.hh:143
void Put(const value_type &val) const
Definition: G4Cache.hh:318
iterator End()
Definition: G4Cache.hh:438
KEYTYPE key_type
Definition: G4Cache.hh:178
void Clear()
Definition: G4Cache.hh:396
iterator Find(const key_type &k)
Definition: G4Cache.hh:444
int G4int
Definition: G4Types.hh:78
G4GLOB_DLL std::ostream G4cout
std::map< key_type, value_type > map_type
Definition: G4Cache.hh:180
map_type::const_iterator const_iterator
Definition: G4Cache.hh:183
virtual ~G4VectorCache()
Definition: G4Cache.hh:338
iterator Begin()
Definition: G4Cache.hh:384
static std::atomic< unsigned int > instancesctr
Definition: G4Cache.hh:124
int id
Definition: G4Cache.hh:122
size_type Size()
Definition: G4Cache.hh:166
void Push_back(const value_type &val)
Definition: G4Cache.hh:362