Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 // G4GeomSplitter 27 // 28 // Class description: 29 // 30 // Utility template class for splitting of RW 31 // classes: G4LogicalVolume, G4Region, G4VPhys 32 // G4PolyhedraSide, G4PVReplica. 33 34 // Author: X.Dong - Initial version from autom 35 // ------------------------------------------- 36 #ifndef G4GEOMSPLITTER_HH 37 #define G4GEOMSPLITTER_HH 38 39 #include "globals.hh" 40 #include "geomwdefs.hh" 41 #include "G4AutoLock.hh" 42 43 template <class T> // T is the private data f 44 class G4GeomSplitter 45 { 46 public: 47 48 G4GeomSplitter() 49 : sharedOffset(nullptr) 50 { 51 G4MUTEXINIT(mutex); 52 } 53 54 T* Reallocate(G4int size) 55 { 56 totalspace = size; 57 return (T *) std::realloc(offset, total 58 } 59 60 G4int CreateSubInstance() 61 // Invoked by the master or work thread 62 // whenever a new split class instance i 63 { 64 G4AutoLock l(&mutex); 65 ++totalobj; 66 if (totalobj > totalspace) 67 { 68 offset = Reallocate(totalspace+512); 69 if (offset == nullptr) 70 { 71 G4Exception("G4GeomSPlitter::Create 72 "OutOfMemory", FatalExc 73 } 74 sharedOffset = offset; 75 } 76 return (totalobj - 1); 77 } 78 79 void CopyMasterContents() 80 { 81 G4AutoLock l(&mutex); 82 std::memcpy(offset, sharedOffset, totals 83 } 84 85 void SlaveCopySubInstanceArray() 86 // Invoked by each worker thread to copy 87 // from the master thread. 88 { 89 G4AutoLock l(&mutex); 90 if (offset != nullptr) { return; } 91 offset = Reallocate(totalspace); 92 if (offset == nullptr) 93 { 94 G4Exception("G4GeomSplitter::SlaveCopy 95 "OutOfMemory", FatalExcept 96 } 97 l.unlock(); 98 CopyMasterContents(); 99 } 100 101 void SlaveInitializeSubInstance() 102 // Invoked by each worker thread to crea 103 // initialize each subinstance using a p 104 // the subclass. 105 { 106 G4AutoLock l(&mutex); 107 if (offset != nullptr) { return; } 108 offset = Reallocate(totalspace); 109 110 if (offset == nullptr) 111 { 112 G4Exception("G4GeomSplitter::SlaveInit 113 "OutOfMemory", FatalExcept 114 } 115 116 for (G4int i=0 ; i<totalspace; ++i) 117 { 118 offset[i].initialize(); 119 } 120 } 121 122 void SlaveReCopySubInstanceArray() 123 // Invoked by each worker thread at star 124 // to copy again all the subinstance arr 125 // To cope with user's changes in Geomet 126 // in a volume 127 { 128 if (offset == nullptr) 129 { 130 SlaveInitializeSubInstance(); 131 G4Exception("G4GeomSPlitter::SlaveReCo 132 "MissingInitialisation", J 133 "Must be called after Init 134 } 135 CopyMasterContents(); 136 } 137 138 void FreeSlave() 139 // Invoked by all threads to free the su 140 { 141 if (offset == nullptr) { return; } 142 std::free( offset ); 143 offset = nullptr; 144 } 145 146 // Extension - to allow sharing of workspa 147 148 T* GetOffset() { return offset; } 149 150 void UseWorkArea( T* newOffset ) 151 // Use recycled work area - which was cr 152 { 153 if( (offset!=nullptr) && (offset!=newOff 154 { 155 G4Exception("G4GeomSplitter::UseWorks 156 "TwoWorkspaces", FatalExc 157 "Thread already has works 158 } 159 offset= newOffset; 160 } 161 162 T* FreeWorkArea() 163 // Detach this thread from this Location 164 // The object which calls this method is 165 { 166 T* offsetRet = offset; 167 offset = nullptr; 168 return offsetRet; 169 } 170 171 public: 172 173 G4GEOM_DLL static G4ThreadLocal T* offset; 174 175 private: 176 177 G4int totalobj{0}; 178 G4int totalspace{0}; 179 T* sharedOffset; 180 G4Mutex mutex; 181 }; 182 183 template <typename T> G4ThreadLocal T* G4GeomS 184 185 #endif 186