ECCE @ EIC Software
Reference for
ECCE @ EIC
simulation and reconstruction software on GitHub
Home page
Related Pages
Modules
Namespaces
Classes
Files
External Links
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Groups
Pages
G4VUPLSplitter.hh
Go to the documentation of this file.
Or view
the newest version in sPHENIX GitHub for file G4VUPLSplitter.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
//
27
//
28
//
29
// ------------------------------------------------------------
30
//
31
// GEANT 4 class header file
32
//
33
// ---------------- G4UPLSplitter ----------------
34
//
35
// Utility template class for splitting RW data for thread-safety from
36
// classes: G4UserPhysicsList, G4VPhysicsConstructor and G4CModularPhsyicsList
37
//
38
// ------------------------------------------------------------
39
// History:
40
// 01.25.2009 Xin Dong: First implementation from automatic MT conversion.
41
// ------------------------------------------------------------
42
#ifndef G4VUPLSPLITTER_HH
43
#define G4VUPLSPLITTER_HH
44
45
#include <stdlib.h>
46
47
#include "
globals.hh
"
48
#include "
rundefs.hh
"
49
#include "
G4AutoLock.hh
"
50
//
51
// This class implements the split-mechanism for shared objects.
52
// Let's see how it works.
53
// In the split-class we have an instance of this class and an G4int instanceID
54
// Every time, in the master thread a new instance of the split-class
55
// is created the constructor calls:
56
// instanceID = g4vuplsplitter.CreateInstance();
57
// This creates in memory an "array", pointed by "sharedOffset" of capacity "totalspace"
58
// The array contains "totalobj" (<=totalspace) instances (i.e. the array has
59
// un-initialized spaces)
60
// Note that also the TLS variables "offset" and "workertotalspace" have also the same stuff
61
// When a worker thread is started we can call g4vuplsplitter.NewSubInstances()
62
// This will simply allocate enough space in the TLS space "offset" and call
63
// T::initialize() onto the new created methods.
64
// Alternatively one can call, when the worker thread start, g4vuplsplitter.workerCopySubInstanceArray()
65
// That will copy the content of master thread "array" into the TLS one
66
67
// To see this stuff in action see:
68
// G4VUserPhysicsList class and G4WorkerThread classes.
69
70
template
<
class
T>
// T is the private data from the object to be split
71
class
G4VUPLSplitter
72
{
73
public
:
74
75
G4VUPLSplitter
() :
totalobj
(0),
totalspace
(0),
sharedOffset
(0)
76
{
77
G4MUTEXINIT
(
mutex
);
78
}
79
80
G4int
CreateSubInstance
()
81
// Invoked by the master thread to create a new subinstance
82
// whenever a new split class instance is created.
83
// This is called by constructor of shared classes, thus only master thread
84
// calls this
85
{
86
G4AutoLock
l(&
mutex
);
87
//One more instance
88
totalobj
++;
89
//If the number of objects is larger than the available spaces,
90
//a re-allocation is needed
91
if
(
totalobj
>
workertotalspace
)
92
{
93
l.
unlock
();
94
NewSubInstances
();
95
l.
lock
();
96
}
97
//Since this is called by Master thread, we can remember this
98
totalspace
=
workertotalspace
;
99
sharedOffset
=
offset
;
100
return
(
totalobj
- 1);
101
}
102
103
void
NewSubInstances
()
104
// Invoked by each worker thread to grow the subinstance array and
105
// initialize each new subinstance using a particular method defined
106
// by the subclass.
107
{
108
G4AutoLock
l(&
mutex
);
109
if
(
workertotalspace
>=
totalobj
) {
return
; }
110
//Remember current large size
111
G4int
originaltotalspace =
workertotalspace
;
112
//Increase its size by some value (purely arbitrary)
113
workertotalspace
=
totalobj
+ 512;
114
//Now re-allocate new space
115
offset
= (
T
*) realloc(
offset
,
workertotalspace
*
sizeof
(
T
));
116
if
(
offset
== 0)
117
{
118
G4Exception
(
"G4VUPLSplitter::NewSubInstances()"
,
119
"OutOfMemory"
,
FatalException
,
"Cannot malloc space!"
);
120
return
;
121
}
122
//The newly created objects need to be initialized
123
for
(
G4int
i = originaltotalspace; i <
workertotalspace
; i++)
124
{
125
offset
[i].initialize();
126
}
127
}
128
129
void
FreeWorker
()
130
// Invoked by all threads to free the subinstance array.
131
{
132
if
(!
offset
) {
return
; }
133
free(
offset
);
134
offset
= 0;
135
}
136
137
T
*
GetOffset
() {
return
offset
; }
138
139
void
UseWorkArea
(
T
* newOffset )
140
{
141
// Use recycled work area - which was created previously
142
if
(
offset
&&
offset
!=newOffset )
143
{
144
G4Exception
(
"G4VUPLSplitter::UseWorkspace()"
,
145
"TwoWorkspaces"
,
FatalException
,
146
"Thread already has workspace - cannot use another."
);
147
}
148
offset
= newOffset;
149
// totalobj= numObjects;
150
// totalspace= numSpace;
151
}
152
153
T
*
FreeWorkArea
()
// G4int* numObjects, G4int* numSpace)
154
{
155
// Detach this thread from this Location
156
// The object which calls this method is responsible for it.
157
//
158
T
* offsetRet=
offset
;
159
160
offset
= 0;
161
162
return
offsetRet;
163
}
164
165
void
WorkerCopySubInstanceArray
()
166
//Invoked by each worker thread to copy all subinstances array from
167
//the master thread
168
{
169
if
(
offset
)
return
;
170
//Since this is called by worker threds, totalspace is some valid number > 0
171
//Remember totalspace is the number of availabel slots from master.
172
//We are sure that it has valid data
173
G4AutoLock
l(&
mutex
);
174
offset
= (
T
*)realloc(
offset
,
totalspace
*
sizeof
(
T
));
175
if
(
offset
== 0)
176
{
177
G4Exception
(
"G4VUPLSplitter::WorkerCopySubInstanceArray()"
,
178
"OutOfMemory"
,
FatalException
,
"Cannot malloc space!"
);
179
return
;
180
}
181
//Now just copy from master thread (sharedOffset)
182
memcpy(
offset
,
sharedOffset
,
totalspace
*
sizeof
(
T
));
183
}
184
public
:
185
186
G4RUN_DLL
G4ThreadLocalStatic
G4int
workertotalspace
;
//Per-thread available number of slots
187
G4RUN_DLL
G4ThreadLocalStatic
T
*
offset
;
//Pointer to first instance of an array
188
189
private
:
190
G4int
totalobj
;
//Total number of instances from master thread
191
G4int
totalspace
;
// Available number of "slots"
192
T
*
sharedOffset
;
193
G4Mutex
mutex
;
194
};
195
196
template
<
typename
T>
G4ThreadLocal
G4int
G4VUPLSplitter<T>::workertotalspace
=0;
197
template
<
typename
T>
G4ThreadLocal
T
*
G4VUPLSplitter<T>::offset
=0;
198
199
#endif
geant4
tree
geant4-10.6-release
source
run
include
G4VUPLSplitter.hh
Built by
Jin Huang
. updated:
Wed Jun 29 2022 17:25:53
using
1.8.2 with
ECCE GitHub integration