Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:58:13

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 // Class Description:
0027 //
0028 // A class for fast allocation of STL vectors through a static pool.
0029 // It's meant to be used as alternative allocator for STL vectors.
0030        
0031 //      ---------------- G4EnhancedVecAllocator ----------------
0032 //
0033 // Original author: X.Dong (NorthEastern Univ.), November 2009
0034 // Reviewed implementation: G.Cosmo (CERN), December 2009
0035 // ------------------------------------------------------------
0036 #ifndef G4EnhancedVecAllocator_hh
0037 #define G4EnhancedVecAllocator_hh 1
0038 
0039 #include "G4Types.hh"
0040 
0041 typedef struct
0042 {
0043   G4int isAllocated;
0044   char *address;
0045 } G4ChunkType;
0046 
0047 typedef struct
0048 {
0049   std::size_t size;
0050   G4int totalspace;
0051   G4ChunkType *preAllocated;
0052 } G4ChunkIndexType;
0053 
0054 class G4AllocStats
0055 {
0056   // --------------------------------------------------------------------
0057   // Utility class, placeholder for global data on allocation.
0058   // Initialisation to zero of the data below *must* be added ONCE only
0059   // directly in the client code, where this allocator is to be applied
0060   // --------------------------------------------------------------------
0061 
0062   public:
0063 
0064     static G4ThreadLocal G4ChunkIndexType * allocStat;
0065     static G4ThreadLocal G4int totSpace;
0066     static G4ThreadLocal G4int numCat;
0067 };
0068 
0069 template<typename _Tp>
0070 class G4EnhancedVecAllocator : public std::allocator<_Tp>
0071 {
0072   public:
0073 
0074     template<typename _Tp1>
0075     struct rebind { typedef G4EnhancedVecAllocator<_Tp1> other; };
0076 
0077     G4EnhancedVecAllocator() {;}
0078 
0079     G4EnhancedVecAllocator(const G4EnhancedVecAllocator<_Tp>&)
0080       : std::allocator<_Tp>() {;}
0081 
0082     template<typename _Tp1>
0083     G4EnhancedVecAllocator(const G4EnhancedVecAllocator<_Tp1>&)
0084       : std::allocator<_Tp>() {;}
0085 
0086     ~G4EnhancedVecAllocator() {;}
0087 
0088     // override allocate / deallocate
0089     //
0090     void deallocate(_Tp* _Ptr, std::size_t _Count);
0091 #ifdef __IBMCPP__
0092     _Tp* allocate(std::size_t _Count, void * const hint = 0);  // IBM AIX
0093 #else
0094     _Tp* allocate(std::size_t _Count);
0095 #endif
0096 };
0097 
0098 // ------------------------------------------------------------
0099 // Inline implementations
0100 // ------------------------------------------------------------
0101 
0102 // ************************************************************
0103 // deallocate
0104 // ************************************************************
0105 //
0106 template<typename _Tp>
0107 void G4EnhancedVecAllocator<_Tp>::deallocate(_Tp* _Ptr, std::size_t _Count)
0108 {
0109   G4int found = -1;
0110   if (G4AllocStats::allocStat != 0)
0111   {
0112     for (auto j = 0 ; j < G4AllocStats::numCat ; ++j)
0113     {
0114       if (G4AllocStats::allocStat[j].size == (_Count * sizeof(_Tp)))
0115       {
0116         found = j;
0117         break;
0118       }
0119     }
0120   }
0121   // assert(found != -1);
0122 
0123   G4ChunkIndexType& chunk = G4AllocStats::allocStat[found];
0124 
0125   for (auto k = 0; k < chunk.totalspace; ++k)
0126   {
0127     if ( (chunk.preAllocated[k]).address == ((char *) _Ptr))
0128     {
0129       // assert((chunk.preAllocated[k]).isAllocated==1);
0130       (chunk.preAllocated[k]).isAllocated = 0;
0131       return;
0132     }
0133   }
0134 }
0135 
0136 // ************************************************************
0137 // allocate
0138 // ************************************************************
0139 //
0140 #ifdef __IBMCPP__
0141 template<typename _Tp>
0142 _Tp* G4EnhancedVecAllocator<_Tp>::allocate(std::size_t _Count, void * const hint)
0143 #else
0144 template<typename _Tp>
0145 _Tp* G4EnhancedVecAllocator<_Tp>::allocate(std::size_t _Count)
0146 #endif
0147 {
0148   std::size_t totalsize = _Count * sizeof(_Tp);
0149 
0150   G4int found = -1;
0151   if (G4AllocStats::allocStat != 0)
0152   {
0153     for (auto j = 0 ; j < G4AllocStats::numCat ; ++j)
0154     {
0155       if (G4AllocStats::allocStat[j].size == totalsize)
0156       {
0157         found = j;
0158         break;
0159       } 
0160     }
0161   }   
0162 
0163   if (found == -1)  // Find the new size
0164   {
0165     ++G4AllocStats::numCat;
0166     if (G4AllocStats::numCat > G4AllocStats::totSpace)
0167     {
0168       G4AllocStats::totSpace = G4AllocStats::totSpace + 128;
0169         // heuristic parameter for different sizes
0170 
0171       G4AllocStats::allocStat =
0172            (G4ChunkIndexType *) realloc(G4AllocStats::allocStat,
0173            sizeof(G4ChunkIndexType) * G4AllocStats::totSpace);
0174         // This value must be different than zero; otherwise means
0175         // failure in allocating extra space !
0176       // assert(G4AllocStats::allocStat != 0);
0177     }
0178 
0179     G4AllocStats::allocStat[G4AllocStats::numCat-1].size = totalsize;
0180     G4AllocStats::allocStat[G4AllocStats::numCat-1].totalspace = 0;
0181     G4AllocStats::allocStat[G4AllocStats::numCat-1].preAllocated = 0;
0182 
0183     found = G4AllocStats::numCat - 1;
0184     G4ChunkIndexType& chunk = G4AllocStats::allocStat[found];
0185 
0186     chunk.totalspace = 512;
0187       // heuristic for the number of STL vector instances
0188 
0189     chunk.preAllocated = (G4ChunkType *) realloc(chunk.preAllocated,
0190                          sizeof(G4ChunkType) * chunk.totalspace);
0191       // This value must be different than zero; otherwise means
0192       // failure in allocating extra space for pointers !
0193     // assert(chunk.preAllocated != 0);
0194 
0195     char *newSpace1 = (char *) malloc(totalsize * 512);
0196       // This pointer must be different than zero; otherwise means
0197       // failure in allocating extra space for instances !
0198     // assert(newSpace1 != 0);
0199 
0200     for (auto k = 0; k < 512 ; ++k)
0201     {
0202       (chunk.preAllocated[k]).isAllocated = 0;
0203       (chunk.preAllocated[k]).address = newSpace1+totalsize*k;
0204     }
0205 
0206     (chunk.preAllocated[0]).isAllocated = 1;
0207     return (_Tp*)((chunk.preAllocated[0]).address);
0208   }
0209 
0210   G4ChunkIndexType& chunk = G4AllocStats::allocStat[found];
0211 
0212   // assert(chunk.size == totalsize);
0213 
0214   for (auto k = 0; k < chunk.totalspace; ++k)
0215   {
0216     if ((chunk.preAllocated[k]).isAllocated == 0)
0217     { 
0218       (chunk.preAllocated[k]).isAllocated = 1;
0219       return (_Tp*)((chunk.preAllocated[k]).address);
0220     }
0221   }
0222 
0223   G4int originalchunknumber = chunk.totalspace;
0224       
0225   chunk.totalspace += 512;  // heuristic for the number of STL vector instances
0226 
0227   chunk.preAllocated = (G4ChunkType *) realloc(chunk.preAllocated,
0228                        sizeof(G4ChunkType) * chunk.totalspace);
0229     // This value must be different than zero; otherwise means
0230     // failure in allocating extra space for pointers !
0231   // assert(chunk.preAllocated != 0);
0232 
0233   char *newSpace = (char *) malloc(totalsize * 512);
0234     // This pointer must be different than zero; otherwise means
0235     // failure in allocating extra space for instances !
0236   // assert(newSpace != 0);
0237 
0238   for (auto k = 0; k < 512 ; ++k)
0239   {
0240     (chunk.preAllocated[originalchunknumber+k]).isAllocated = 0;
0241     (chunk.preAllocated[originalchunknumber+k]).address = newSpace+totalsize*k;
0242   }
0243 
0244   (chunk.preAllocated[originalchunknumber]).isAllocated = 1;
0245 
0246   return (_Tp*)((chunk.preAllocated[originalchunknumber]).address);
0247 }
0248 
0249 // ************************************************************
0250 // operator==
0251 // ************************************************************
0252 //
0253 template<typename _T1, typename _T2>
0254 inline G4bool operator==(const G4EnhancedVecAllocator<_T1>&,
0255                          const G4EnhancedVecAllocator<_T2>&)
0256 { return true; }
0257 
0258 // ************************************************************
0259 // operator!=
0260 // ************************************************************
0261 //
0262 template<typename _T1, typename _T2>
0263 inline G4bool operator!=(const G4EnhancedVecAllocator<_T1>&,
0264                          const G4EnhancedVecAllocator<_T2>&)
0265 { return false; }
0266 
0267 #endif