Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:59:15

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 // G4TWorkspacePool
0027 //
0028 // Class description:
0029 //
0030 // Create and hold a pointer to Workspace.
0031 // This class holds a thread-private static instance of the template
0032 // parameter workspace.
0033 //
0034 // The concrete implementation of workspace objects are responsible for
0035 // instantiating a singleton instance of this pool.
0036 //
0037 // Recycling of this pool can enable reuse among different threads in
0038 // task-based - or 'on-demand' - simulation.
0039 
0040 // Authors: J.Apostolakis, A.Dotti - 24 October 2014
0041 // Revisions: G.Cosmo - 21 Obctober 2016, revised pool initialisation
0042 // ------------------------------------------------------------
0043 #ifndef G4TWORKSPACEPOOL_HH
0044 #define G4TWORKSPACEPOOL_HH 1
0045 
0046 #include "globals.hh"
0047 #include "tls.hh"
0048 
0049 template <class T>
0050 class G4TWorkspacePool
0051 {
0052  public:
0053   inline T* CreateWorkspace();
0054   // For use with simple MT mode - each thread gets a workspace
0055   // and uses it until end
0056 
0057   inline void CreateAndUseWorkspace();
0058   // Create it (as above) and use it
0059 
0060   inline T* FindOrCreateWorkspace();
0061   // For use with 'dynamic' model of threading - workspaces can be recycled
0062   // Reuse an existing workspace - or create a new one if needed.
0063   // This will never fail, except if system is out of resources
0064 
0065   inline T* GetWorkspace() { return fMyWorkspace; }
0066   // Give back the existing, active workspace for my thread / task
0067 
0068   inline void Recycle(T* myWrkSpace);
0069   // Keep the unused Workspace - for recycling
0070 
0071   inline void CleanUpAndDestroyAllWorkspaces();
0072   // To be called once at the end of the job
0073 
0074   G4TWorkspacePool() {}
0075   ~G4TWorkspacePool() {}
0076 
0077  private:
0078   static G4ThreadLocal T* fMyWorkspace;
0079   // The thread's workspace - if assigned
0080 };
0081 
0082 template <typename T>
0083 G4ThreadLocal T* G4TWorkspacePool<T>::fMyWorkspace = nullptr;
0084 
0085 // -----------------------------
0086 // Inline methods implementation
0087 // -----------------------------
0088 
0089 template <class T>
0090 T* G4TWorkspacePool<T>::CreateWorkspace()
0091 {
0092   T* wrk = nullptr;
0093   if(fMyWorkspace == nullptr)
0094   {
0095     wrk = new T;
0096     if(wrk == nullptr)
0097     {
0098       G4Exception("G4TWorspacePool<someType>::CreateWorkspace()", "MemoryError",
0099                   FatalException, "Failed to create workspace.");
0100     }
0101     else
0102     {
0103       fMyWorkspace = wrk;
0104     }
0105   }
0106   else
0107   {
0108     G4Exception("ParticlesWorspacePool::CreateWorkspace()", "InvalidCondition",
0109                 FatalException,
0110                 "Cannot create workspace twice for the same thread.");
0111     wrk = fMyWorkspace;
0112   }
0113   return wrk;
0114 }
0115 
0116 template <class T>
0117 void G4TWorkspacePool<T>::CreateAndUseWorkspace()
0118 {
0119   (this->CreateWorkspace())->UseWorkspace();
0120 }
0121 
0122 template <class T>
0123 T* G4TWorkspacePool<T>::FindOrCreateWorkspace()
0124 {
0125   T* wrk = fMyWorkspace;
0126   if(wrk == nullptr)
0127   {
0128     wrk = this->CreateWorkspace();
0129   }
0130   wrk->UseWorkspace();
0131 
0132   fMyWorkspace = wrk;  // assign it for use by this thread.
0133   return wrk;
0134 }
0135 
0136 template <class T>
0137 void G4TWorkspacePool<T>::Recycle(T* myWrkSpace)
0138 {
0139   myWrkSpace->ReleaseWorkspace();
0140   delete myWrkSpace;
0141 }
0142 
0143 template <class T>
0144 void G4TWorkspacePool<T>::CleanUpAndDestroyAllWorkspaces()
0145 {
0146   if(fMyWorkspace != nullptr)
0147   {
0148     fMyWorkspace->DestroyWorkspace();
0149     delete fMyWorkspace;
0150     fMyWorkspace = nullptr;
0151   }
0152 }
0153 
0154 #endif