Geant4-11
G4GeomSplitter.hh
Go to the documentation of this file.
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// G4GeomSplitter
27//
28// Class description:
29//
30// Utility template class for splitting of RW data for thread-safety from
31// classes: G4LogicalVolume, G4Region, G4VPhysicalVolume, G4PolyconeSide
32// G4PolyhedraSide, G4PVReplica.
33
34// Author: X.Dong - Initial version from automatic MT conversion, 01.25.09.
35// ------------------------------------------------------------------------
36#ifndef G4GEOMSPLITTER_HH
37#define G4GEOMSPLITTER_HH
38
39#include "globals.hh"
40#include "geomwdefs.hh"
41#include "G4AutoLock.hh"
42
43template <class T> // T is the private data from the object to be split
45{
46 public:
47
49 : totalobj(0), totalspace(0), sharedOffset(nullptr)
50 {
52 }
53
55 {
56 totalspace = size;
57 return (T *) std::realloc(offset, totalspace * sizeof(T));
58 }
59
61 // Invoked by the master or work thread to create a new subinstance
62 // whenever a new split class instance is created.
63 {
64 G4AutoLock l(&mutex);
65 ++totalobj;
66 if (totalobj > totalspace)
67 {
69 if (offset == nullptr)
70 {
71 G4Exception("G4GeomSPlitter::CreateSubInstance()",
72 "OutOfMemory", FatalException, "Cannot malloc space!");
73 }
75 }
76 return (totalobj - 1);
77 }
78
80 {
81 G4AutoLock l(&mutex);
82 std::memcpy(offset, sharedOffset, totalspace * sizeof(T));
83 }
84
86 // Invoked by each worker thread to copy all the subinstance array
87 // from the master thread.
88 {
89 G4AutoLock l(&mutex);
90 if (offset != nullptr) { return; }
92 if (offset == nullptr)
93 {
94 G4Exception("G4GeomSplitter::SlaveCopySubInstanceArray()",
95 "OutOfMemory", FatalException, "Cannot malloc space!");
96 }
97 l.unlock();
99 }
100
102 // Invoked by each worker thread to create the subinstance array and
103 // initialize each subinstance using a particular method defined by
104 // the subclass.
105 {
106 G4AutoLock l(&mutex);
107 if (offset != nullptr) { return; }
109
110 if (offset == nullptr)
111 {
112 G4Exception("G4GeomSplitter::SlaveInitializeSubInstance()",
113 "OutOfMemory", FatalException, "Cannot malloc space!");
114 }
115
116 for (G4int i=0 ; i<totalspace; ++i)
117 {
118 offset[i].initialize();
119 }
120 }
121
123 // Invoked by each worker thread at start of a run (2nd or later)
124 // to copy again all the subinstance array from the master thread.
125 // To cope with user's changes in Geometry - e.g. change of material
126 // in a volume
127 {
128 if (offset == nullptr)
129 {
131 G4Exception("G4GeomSPlitter::SlaveReCopySubInstance()",
132 "MissingInitialisation", JustWarning,
133 "Must be called after Initialisation or first Copy.");
134 }
136 }
137
139 // Invoked by all threads to free the subinstance array.
140 {
141 if (offset == nullptr) { return; }
142 std::free( offset );
143 offset = nullptr;
144 }
145
146 // Extension - to allow sharing of workspaces
147
148 T* GetOffset() { return offset; }
149
150 void UseWorkArea( T* newOffset )
151 // Use recycled work area - which was created previously
152 {
153 if( (offset!=nullptr) && (offset!=newOffset) )
154 {
155 G4Exception("G4GeomSplitter::UseWorkspace()",
156 "TwoWorkspaces", FatalException,
157 "Thread already has workspace - cannot use another.");
158 }
159 offset= newOffset;
160 }
161
163 // Detach this thread from this Location.
164 // The object which calls this method is responsible for it.
165 {
166 T* offsetRet = offset;
167 offset = nullptr;
168 return offsetRet;
169 }
170
171 public:
172
174
175 private:
176
181};
182
183template <typename T> G4ThreadLocal T* G4GeomSplitter<T>::offset = nullptr;
184
185#endif
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
std::mutex G4Mutex
Definition: G4Threading.hh:81
#define G4MUTEXINIT(mutex)
Definition: G4Threading.hh:87
int G4int
Definition: G4Types.hh:85
void SlaveReCopySubInstanceArray()
void SlaveInitializeSubInstance()
static G4GEOM_DLL G4ThreadLocal T * offset
G4int CreateSubInstance()
void SlaveCopySubInstanceArray()
T * Reallocate(G4int size)
void CopyMasterContents()
void UseWorkArea(T *newOffset)
#define G4GEOM_DLL
Definition: geomwdefs.hh:44
#define G4ThreadLocal
Definition: tls.hh:77