File indexing completed on 2026-07-17 08:30:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #ifndef G4GEOMSPLITTER_HH
0037 #define G4GEOMSPLITTER_HH
0038
0039 #include "globals.hh"
0040 #include "geomwdefs.hh"
0041 #include "G4AutoLock.hh"
0042
0043
0044
0045
0046
0047
0048
0049 template <class T>
0050 class G4GeomSplitter
0051 {
0052 public:
0053
0054
0055
0056
0057 G4GeomSplitter()
0058 : sharedOffset(nullptr)
0059 {
0060 G4MUTEXINIT(mutex);
0061 }
0062
0063
0064
0065
0066 T* Reallocate(G4int size)
0067 {
0068 totalspace = size;
0069 return (T *) std::realloc(offset, totalspace * sizeof(T));
0070 }
0071
0072
0073
0074
0075
0076 G4int CreateSubInstance()
0077 {
0078 G4AutoLock l(&mutex);
0079 ++totalobj;
0080 if (totalobj > totalspace)
0081 {
0082 offset = Reallocate(totalspace+512);
0083 if (offset == nullptr)
0084 {
0085 G4Exception("G4GeomSPlitter::CreateSubInstance()",
0086 "OutOfMemory", FatalException, "Cannot malloc space!");
0087 }
0088 sharedOffset = offset;
0089 }
0090 return (totalobj - 1);
0091 }
0092
0093
0094
0095
0096 void CopyMasterContents()
0097 {
0098 G4AutoLock l(&mutex);
0099 std::memcpy(offset, sharedOffset, totalspace * sizeof(T));
0100 }
0101
0102
0103
0104
0105
0106 void SlaveCopySubInstanceArray()
0107 {
0108 G4AutoLock l(&mutex);
0109 if (offset != nullptr) { return; }
0110 offset = Reallocate(totalspace);
0111 if (offset == nullptr)
0112 {
0113 G4Exception("G4GeomSplitter::SlaveCopySubInstanceArray()",
0114 "OutOfMemory", FatalException, "Cannot malloc space!");
0115 }
0116 l.unlock();
0117 CopyMasterContents();
0118 }
0119
0120
0121
0122
0123
0124
0125 void SlaveInitializeSubInstance()
0126 {
0127 G4AutoLock l(&mutex);
0128 if (offset != nullptr) { return; }
0129 offset = Reallocate(totalspace);
0130
0131 if (offset == nullptr)
0132 {
0133 G4Exception("G4GeomSplitter::SlaveInitializeSubInstance()",
0134 "OutOfMemory", FatalException, "Cannot malloc space!");
0135 }
0136
0137 for (G4int i=0 ; i<totalspace; ++i)
0138 {
0139 offset[i].initialize();
0140 }
0141 }
0142
0143
0144
0145
0146
0147
0148
0149 void SlaveReCopySubInstanceArray()
0150 {
0151 if (offset == nullptr)
0152 {
0153 SlaveInitializeSubInstance();
0154 G4Exception("G4GeomSPlitter::SlaveReCopySubInstance()",
0155 "MissingInitialisation", JustWarning,
0156 "Must be called after Initialisation or first Copy.");
0157 }
0158 CopyMasterContents();
0159 }
0160
0161
0162
0163
0164 void FreeSlave()
0165 {
0166 if (offset == nullptr) { return; }
0167 std::free( offset );
0168 offset = nullptr;
0169 }
0170
0171
0172
0173
0174
0175
0176 T* GetOffset() { return offset; }
0177
0178
0179
0180
0181 void UseWorkArea( T* newOffset )
0182 {
0183 if( (offset!=nullptr) && (offset!=newOffset) )
0184 {
0185 G4Exception("G4GeomSplitter::UseWorkspace()",
0186 "TwoWorkspaces", FatalException,
0187 "Thread already has workspace - cannot use another.");
0188 }
0189 offset = newOffset;
0190 }
0191
0192
0193
0194
0195
0196 T* FreeWorkArea()
0197 {
0198 T* offsetRet = offset;
0199 offset = nullptr;
0200 return offsetRet;
0201 }
0202
0203 public:
0204
0205 G4GEOM_DLL static G4ThreadLocal T* offset;
0206
0207 private:
0208
0209 G4int totalobj{0};
0210 G4int totalspace{0};
0211 T* sharedOffset;
0212 G4Mutex mutex;
0213 };
0214
0215 template <typename T> G4ThreadLocal T* G4GeomSplitter<T>::offset = nullptr;
0216
0217 #endif