G4EnhancedVecAllocator.hh

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id$
00028 //
00029 // 
00030 // ------------------------------------------------------------
00031 // GEANT 4 class header file 
00032 //
00033 // Class Description:
00034 //
00035 // A class for fast allocation of STL vectors through a static pool.
00036 // It's meant to be used as alternative allocator for STL vectors.
00037        
00038 //      ---------------- G4EnhancedVecAllocator ----------------
00039 //
00040 // Original author: X.Dong (NorthEastern Univ.), November 2009
00041 // Reviewed implementation: G.Cosmo (CERN), December 2009
00042 // ------------------------------------------------------------
00043 
00044 #ifndef G4EnhancedVecAllocator_h
00045 #define G4EnhancedVecAllocator_h 1
00046 
00047 #include "G4Types.hh"
00048 
00049 // #include <cstdlib>
00050 
00051 typedef struct
00052 {
00053   G4int isAllocated;
00054   char *address;
00055 } G4ChunkType;
00056 
00057 typedef struct
00058 {
00059   size_t size;
00060   G4int totalspace;
00061   G4ChunkType *preAllocated;
00062 } G4ChunkIndexType;
00063 
00064 class G4AllocStats
00065 {
00066   // --------------------------------------------------------------------
00067   // Utility class, placeholder for global data on allocation.
00068   // Initialisation to zero of the data below *must* be added ONCE only
00069   // directly in the client code, where this allocator is to be applied
00070   // --------------------------------------------------------------------
00071 
00072   public:
00073 
00074     static G4ChunkIndexType * allocStat;
00075     static G4int totSpace;
00076     static G4int numCat;
00077 };
00078 
00079 template<typename _Tp>
00080 class G4EnhancedVecAllocator : public std::allocator<_Tp>
00081 {
00082   public:
00083 
00084     template<typename _Tp1>
00085     struct rebind { typedef G4EnhancedVecAllocator<_Tp1> other; };
00086 
00087     G4EnhancedVecAllocator() {;}
00088 
00089     G4EnhancedVecAllocator(const G4EnhancedVecAllocator<_Tp>&)
00090       : std::allocator<_Tp>() {;}
00091 
00092     template<typename _Tp1>
00093     G4EnhancedVecAllocator(const G4EnhancedVecAllocator<_Tp1>&)
00094       : std::allocator<_Tp>() {;}
00095 
00096     ~G4EnhancedVecAllocator() {;}
00097 
00098     // override allocate / deallocate
00099     //
00100     void deallocate(_Tp* _Ptr, size_t _Count);
00101 #ifdef __IBMCPP__
00102     _Tp* allocate(size_t _Count, void * const hint = 0);  // IBM AIX
00103 #else
00104     _Tp* allocate(size_t _Count);
00105 #endif
00106 };
00107 
00108 // ------------------------------------------------------------
00109 // Inline implementations
00110 // ------------------------------------------------------------
00111 
00112 // ************************************************************
00113 // deallocate
00114 // ************************************************************
00115 //
00116 template<typename _Tp>
00117 void G4EnhancedVecAllocator<_Tp>::deallocate(_Tp* _Ptr, size_t _Count)
00118 {
00119   G4int found = -1;
00120   for (register int j = 0 ; j < G4AllocStats::numCat ; j++)
00121   {
00122     if ( (G4AllocStats::allocStat != 0)
00123       && (G4AllocStats::allocStat[j].size == (_Count * sizeof(_Tp))))
00124     {
00125       found = j;
00126       break;
00127     }
00128   }
00129   // assert(found != -1);
00130 
00131   for (register int k = 0; k < G4AllocStats::allocStat[found].totalspace; k++)
00132   {
00133     if ( ((G4AllocStats::allocStat[found]).preAllocated[k]).address
00134       == ((char *) _Ptr))
00135     {
00136    // assert(((G4AllocStats::allocStat[found]).preAllocated[k]).isAllocated==1);
00137       ((G4AllocStats::allocStat[found]).preAllocated[k]).isAllocated = 0;
00138       return;
00139     }
00140   }
00141 }
00142 
00143 // ************************************************************
00144 // allocate
00145 // ************************************************************
00146 //
00147 #ifdef __IBMCPP__
00148 template<typename _Tp>
00149 _Tp* G4EnhancedVecAllocator<_Tp>::allocate(size_t _Count, void * const hint)
00150 #else
00151 template<typename _Tp>
00152 _Tp* G4EnhancedVecAllocator<_Tp>::allocate(size_t _Count)
00153 #endif
00154 {
00155   size_t totalsize = _Count * sizeof(_Tp);
00156 
00157   G4int found = -1;
00158   for (register int j = 0 ; j < G4AllocStats::numCat ; j++)
00159   {
00160     if ( (G4AllocStats::allocStat != 0)
00161       && (G4AllocStats::allocStat[j].size == totalsize) )
00162     {
00163       found = j;
00164       break;
00165     } 
00166   }   
00167 
00168   if (found == -1)  // Find the new size
00169   {
00170     G4AllocStats::numCat++;
00171     if (G4AllocStats::numCat > G4AllocStats::totSpace)
00172     {
00173       G4AllocStats::totSpace = G4AllocStats::totSpace + 128;
00174         // heuristic parameter for different sizes
00175 
00176       G4AllocStats::allocStat =
00177            (G4ChunkIndexType *) realloc(G4AllocStats::allocStat,
00178            sizeof(G4ChunkIndexType) * G4AllocStats::totSpace);
00179         // This value must be different than zero; otherwise means
00180         // failure in allocating extra space !
00181       // assert(G4AllocStats::allocStat != 0);
00182     }
00183 
00184     G4AllocStats::allocStat[G4AllocStats::numCat-1].size = totalsize;
00185     G4AllocStats::allocStat[G4AllocStats::numCat-1].totalspace = 0;
00186     G4AllocStats::allocStat[G4AllocStats::numCat-1].preAllocated = 0;
00187 
00188     found = G4AllocStats::numCat - 1;
00189 
00190     G4AllocStats::allocStat[found].totalspace = 512;
00191       // heuristic for the number of STL vector instances
00192 
00193     G4AllocStats::allocStat[found].preAllocated =
00194         (G4ChunkType *) realloc(G4AllocStats::allocStat[found].preAllocated,
00195           sizeof(G4ChunkType) * G4AllocStats::allocStat[found].totalspace);
00196       // This value must be different than zero; otherwise means
00197       // failure in allocating extra space for pointers !
00198     // assert(G4AllocStats::allocStat[found].preAllocated != 0);
00199 
00200     char *newSpace1 = (char *) malloc(totalsize * 512);
00201       // This pointer must be different than zero; otherwise means
00202       // failure in allocating extra space for instances !
00203     // assert(newSpace1 != 0);
00204 
00205     for (register int k = 0; k < 512 ; k++)
00206     {
00207       ((G4AllocStats::allocStat[found]).preAllocated[k]).isAllocated = 0;
00208       ((G4AllocStats::allocStat[found]).preAllocated[k]).address =
00209                                                     newSpace1+totalsize*k;
00210     }
00211 
00212     ((G4AllocStats::allocStat[found]).preAllocated[0]).isAllocated = 1;
00213     return (_Tp*)(((G4AllocStats::allocStat[found]).preAllocated[0]).address);
00214   }
00215 
00216   // assert(G4AllocStats::allocStat[found].size == totalsize);
00217 
00218   for (register int k = 0; k < G4AllocStats::allocStat[found].totalspace; k++)
00219   {
00220     if (((G4AllocStats::allocStat[found]).preAllocated[k]).isAllocated == 0)
00221     { 
00222       ((G4AllocStats::allocStat[found]).preAllocated[k]).isAllocated = 1;
00223       return (_Tp*)(((G4AllocStats::allocStat[found]).preAllocated[k]).address);
00224     }
00225   }
00226 
00227   G4int originalchunknumber = G4AllocStats::allocStat[found].totalspace;
00228       
00229   G4AllocStats::allocStat[found].totalspace =      // heuristic for the number
00230     G4AllocStats::allocStat[found].totalspace+512; // of STL vector instances
00231 
00232   G4AllocStats::allocStat[found].preAllocated =
00233     (G4ChunkType *) realloc(G4AllocStats::allocStat[found].preAllocated,
00234       sizeof(G4ChunkType) * G4AllocStats::allocStat[found].totalspace);
00235     // This value must be different than zero; otherwise means
00236     // failure in allocating extra space for pointers !
00237   // assert(G4AllocStats::allocStat[found].preAllocated != 0);
00238 
00239   char *newSpace = (char *) malloc(totalsize * 512);
00240     // This pointer must be different than zero; otherwise means
00241     // failure in allocating extra space for instances !
00242   // assert(newSpace != 0);
00243 
00244   for (register int k = 0; k < 512 ; k++)
00245   {
00246     ((G4AllocStats::allocStat[found]).
00247       preAllocated[originalchunknumber + k]).isAllocated= 0;
00248     ((G4AllocStats::allocStat[found]).
00249       preAllocated[originalchunknumber + k]).address= newSpace+totalsize*k;
00250   }
00251 
00252   ((G4AllocStats::allocStat[found]).preAllocated[originalchunknumber])
00253                                    .isAllocated = 1;
00254 
00255   return (_Tp*)(((G4AllocStats::allocStat[found]).
00256                   preAllocated[originalchunknumber]).address);
00257 }
00258 
00259 // ************************************************************
00260 // operator==
00261 // ************************************************************
00262 //
00263 template<typename _T1, typename _T2>
00264 inline bool operator==(const G4EnhancedVecAllocator<_T1>&,
00265                        const G4EnhancedVecAllocator<_T2>&)
00266 { return true; }
00267 
00268 // ************************************************************
00269 // operator!=
00270 // ************************************************************
00271 //
00272 template<typename _T1, typename _T2>
00273 inline bool operator!=(const G4EnhancedVecAllocator<_T1>&,
00274                        const G4EnhancedVecAllocator<_T2>&)
00275 { return false; }
00276 
00277 #endif

Generated on Mon May 27 17:48:10 2013 for Geant4 by  doxygen 1.4.7