Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/management/include/G4GeomSplitter.hh

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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 
 43 template <class T>  // T is the private data from the object to be split
 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, totalspace * sizeof(T));
 58     }
 59 
 60     G4int CreateSubInstance()
 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       {
 68         offset = Reallocate(totalspace+512);
 69         if (offset == nullptr)
 70         {
 71            G4Exception("G4GeomSPlitter::CreateSubInstance()",
 72                        "OutOfMemory", FatalException, "Cannot malloc space!");
 73         }
 74         sharedOffset = offset;
 75       }
 76       return (totalobj - 1);
 77     }
 78 
 79     void CopyMasterContents()
 80     {
 81       G4AutoLock l(&mutex);
 82       std::memcpy(offset, sharedOffset, totalspace * sizeof(T));
 83     }
 84   
 85     void SlaveCopySubInstanceArray()
 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; }
 91       offset = Reallocate(totalspace);
 92       if (offset == nullptr)
 93       {
 94         G4Exception("G4GeomSplitter::SlaveCopySubInstanceArray()",
 95                     "OutOfMemory", FatalException, "Cannot malloc space!");
 96       }
 97       l.unlock();
 98       CopyMasterContents();
 99     }
100 
101     void SlaveInitializeSubInstance()
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; }
108       offset = Reallocate(totalspace);
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 
122     void SlaveReCopySubInstanceArray()
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       {
130         SlaveInitializeSubInstance();
131         G4Exception("G4GeomSPlitter::SlaveReCopySubInstance()",
132                     "MissingInitialisation", JustWarning,
133                     "Must be called after Initialisation or first Copy.");
134       }
135       CopyMasterContents();
136     }
137   
138     void FreeSlave()
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 
162     T* FreeWorkArea()
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 
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* G4GeomSplitter<T>::offset = nullptr;
184 
185 #endif
186