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