Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer << 3 // * DISCLAIMER * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th << 5 // * The following disclaimer summarizes all the specific disclaimers * 6 // * the Geant4 Collaboration. It is provided << 6 // * of contributors to this software. The specific disclaimers,which * 7 // * conditions of the Geant4 Software License << 7 // * govern, are listed with their locations in: * 8 // * LICENSE and available at http://cern.ch/ << 8 // * http://cern.ch/geant4/license * 9 // * include a list of copyright holders. << 10 // * 9 // * * 11 // * Neither the authors of this software syst 10 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 11 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 12 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 13 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file << 14 // * use. * 16 // * for the full disclaimer and the limitatio << 17 // * 15 // * * 18 // * This code implementation is the result << 16 // * This code implementation is the intellectual property of the * 19 // * technical work of the GEANT4 collaboratio << 17 // * GEANT4 collaboration. * 20 // * By using, copying, modifying or distri << 18 // * By copying, distributing or modifying the Program (or any work * 21 // * any work based on the software) you ag << 19 // * based on the Program) you indicate your acceptance of this * 22 // * use in resulting scientific publicati << 20 // * statement, and all its terms. * 23 // * acceptance of all terms of the Geant4 Sof << 24 // ******************************************* 21 // ******************************************************************** 25 // 22 // 26 // G4Allocator << 23 // >> 24 // $Id: G4Allocator.hh,v 1.11 2002/06/21 16:59:56 gcosmo Exp $ >> 25 // GEANT4 tag $Name: geant4-04-01-patch-01 $ >> 26 // >> 27 // >> 28 // ------------------------------------------------------------ >> 29 // GEANT 4 class header file 27 // 30 // 28 // Class Description: 31 // Class Description: 29 // 32 // 30 // A class for fast allocation of objects to t << 33 // A class for fast allocation of objects to the heap through paging 31 // chunks organised as linked list. It's meant << 34 // mechanism. It's meant to be used by associating it to the object to 32 // it to the object to be allocated and defini << 35 // be allocated and defining for it new and delete operators via 33 // operators via MallocSingle() and FreeSingle << 36 // MallocSingle() and FreeSingle() methods. 34 << 37 35 // ---------------- G4Allocator --------- 38 // ---------------- G4Allocator ---------------- 36 // << 39 // by Tim Bell, September 1995 37 // Author: G.Cosmo (CERN), November 2000 << 40 // ------------------------------------------------------------ 38 // ------------------------------------------- << 39 #ifndef G4Allocator_hh << 40 #define G4Allocator_hh 1 << 41 41 42 #include <cstddef> << 42 #ifndef G4Allocator_h 43 #include <typeinfo> << 43 #define G4Allocator_h 1 44 44 45 #include "G4AllocatorPool.hh" << 45 #include <stdlib.h> >> 46 #include <stddef.h> 46 47 47 class G4AllocatorBase << 48 #include "G4AllocatorPage.hh" 48 { << 49 public: << 50 G4AllocatorBase(); << 51 virtual ~G4AllocatorBase() = default; << 52 virtual void ResetStorage() << 53 virtual std::size_t GetAllocatedSize() const << 54 virtual int GetNoPages() const << 55 virtual std::size_t GetPageSize() const << 56 virtual void IncreasePageSize(unsigned int s << 57 virtual const char* GetPoolType() const << 58 }; << 59 49 60 template <class Type> 50 template <class Type> 61 class G4Allocator : public G4AllocatorBase << 51 class G4Allocator 62 { 52 { 63 public: << 53 public: // with description 64 G4Allocator() throw(); << 65 ~G4Allocator() throw() override; << 66 // Constructor & destructor << 67 << 68 inline Type* MallocSingle(); << 69 inline void FreeSingle(Type* anElement); << 70 // Malloc and Free methods to be used when o << 71 // new and delete operators in the client <T << 72 << 73 inline void ResetStorage() override; << 74 // Returns allocated storage to the free sto << 75 // Note: contents in memory are lost using t << 76 << 77 inline std::size_t GetAllocatedSize() const << 78 // Returns the size of the total memory allo << 79 inline int GetNoPages() const override; << 80 // Returns the total number of allocated pag << 81 inline std::size_t GetPageSize() const overr << 82 // Returns the current size of a page << 83 inline void IncreasePageSize(unsigned int sz << 84 // Resets allocator and increases default pa << 85 << 86 inline const char* GetPoolType() const overr << 87 // Returns the type_info Id of the allocated << 88 << 89 // This public section includes standard met << 90 // required if the allocator is to be used a << 91 // allocator for STL containers. << 92 // NOTE: the code below is a trivial impleme << 93 // this class an STL compliant allocat << 94 // It is anyhow NOT recommended to use << 95 // alternative allocator for STL conta << 96 << 97 using value_type = Type; << 98 using size_type = std::size_t; << 99 using difference_type = ptrdiff_t; << 100 using pointer = Type*; << 101 using const_pointer = const Type*; << 102 using reference = Type&; << 103 using const_reference = const Type&; << 104 << 105 template <class U> << 106 G4Allocator(const G4Allocator<U>& right) thr << 107 : mem(right.mem) << 108 {} << 109 // Copy constructor << 110 << 111 pointer address(reference r) const { return << 112 const_pointer address(const_reference r) con << 113 // Returns the address of values << 114 54 115 pointer allocate(size_type n, void* = nullpt << 55 G4Allocator(); 116 { << 56 ~G4Allocator(); 117 // Allocates space for n elements of type << 57 // Constructor & destructor 118 // << 119 Type* mem_alloc = 0; << 120 if(n == 1) << 121 mem_alloc = MallocSingle(); << 122 else << 123 mem_alloc = static_cast<Type*>(::operato << 124 return mem_alloc; << 125 } << 126 void deallocate(pointer p, size_type n) << 127 { << 128 // Deallocates n elements of type Type, bu << 129 // << 130 if(n == 1) << 131 FreeSingle(p); << 132 else << 133 ::operator delete((void*) p); << 134 return; << 135 } << 136 58 137 void construct(pointer p, const Type& val) { << 59 inline Type* MallocSingle(); 138 // Initialises *p by val << 60 inline void FreeSingle(Type* anElement); 139 void destroy(pointer p) { p->~Type(); } << 61 // Malloc and Free methods to be used when overloading 140 // Destroy *p but doesn't deallocate << 62 // new and delete operators in the client <Type> object 141 63 142 size_type max_size() const throw() << 64 private: 143 { << 144 // Returns the maximum number of elements << 145 // << 146 return 2147483647 / sizeof(Type); << 147 } << 148 65 149 template <class U> << 66 void AddNewPage(); 150 struct rebind << 67 Type* AddNewElement(); 151 { << 68 152 using other = G4Allocator<U>; << 69 private: 153 }; << 70 154 // Rebind allocator to type U << 71 enum { Allocated = 0x47416C, Deleted = 0xB8BE93 }; 155 << 72 156 G4AllocatorPool mem; << 73 G4AllocatorPage<Type> * fPages; 157 // Pool of elements of sizeof(Type) << 74 G4AllocatorUnit<Type> * fFreeList; 158 << 75 159 private: << 76 size_t fUnitSize, fPageSize; 160 const char* tname; << 161 // Type name identifier << 162 }; 77 }; 163 78 164 // ------------------------------------------- 79 // ------------------------------------------------------------ 165 // Inline implementation 80 // Inline implementation 166 // ------------------------------------------- 81 // ------------------------------------------------------------ 167 82 168 // Initialization of the static pool << 169 // << 170 // template <class Type> G4AllocatorPool G4All << 171 << 172 // ******************************************* 83 // ************************************************************ 173 // G4Allocator constructor 84 // G4Allocator constructor 174 // ******************************************* 85 // ************************************************************ 175 // 86 // 176 template <class Type> 87 template <class Type> 177 G4Allocator<Type>::G4Allocator() throw() << 88 G4Allocator<Type>::G4Allocator() 178 : mem(sizeof(Type)) << 179 { 89 { 180 tname = typeid(Type).name(); << 90 fPages = 0; >> 91 fFreeList = 0; >> 92 fUnitSize = sizeof(G4AllocatorUnit<Type>); >> 93 fPageSize = ( (fUnitSize < 512) ? 1024 : (fUnitSize*10) ); >> 94 AddNewPage(); >> 95 return; 181 } 96 } 182 97 183 // ******************************************* 98 // ************************************************************ 184 // G4Allocator destructor 99 // G4Allocator destructor 185 // ******************************************* 100 // ************************************************************ 186 // 101 // 187 template <class Type> 102 template <class Type> 188 G4Allocator<Type>::~G4Allocator() throw() = de << 103 G4Allocator<Type>::~G4Allocator() >> 104 { >> 105 G4AllocatorPage<Type> * aPage; >> 106 G4AllocatorPage<Type> * aNextPage; >> 107 >> 108 aPage = fPages; >> 109 while (aPage != 0) >> 110 { >> 111 aNextPage = aPage->fNext; >> 112 free(aPage->fUnits); >> 113 delete aPage; >> 114 aPage = aNextPage; >> 115 } >> 116 fPages = 0; >> 117 fFreeList = 0; >> 118 return; >> 119 } 189 120 190 // ******************************************* 121 // ************************************************************ 191 // MallocSingle 122 // MallocSingle 192 // ******************************************* 123 // ************************************************************ 193 // 124 // 194 template <class Type> 125 template <class Type> 195 Type* G4Allocator<Type>::MallocSingle() 126 Type* G4Allocator<Type>::MallocSingle() 196 { 127 { 197 return static_cast<Type*>(mem.Alloc()); << 128 Type * anElement; >> 129 >> 130 if (fFreeList != 0) >> 131 { >> 132 fFreeList->deleted = Allocated; >> 133 anElement = &fFreeList->fElement; >> 134 fFreeList = fFreeList->fNext; >> 135 } >> 136 else >> 137 anElement = AddNewElement(); >> 138 return anElement; 198 } 139 } 199 140 200 // ******************************************* 141 // ************************************************************ 201 // FreeSingle 142 // FreeSingle 202 // ******************************************* 143 // ************************************************************ 203 // 144 // 204 template <class Type> 145 template <class Type> 205 void G4Allocator<Type>::FreeSingle(Type* anEle 146 void G4Allocator<Type>::FreeSingle(Type* anElement) 206 { 147 { 207 mem.Free(anElement); << 148 G4AllocatorUnit<Type> * fUnit; 208 return; << 209 } << 210 149 211 // ******************************************* << 150 // The gcc-3.1 compiler will complain and not correctly handle offsets 212 // ResetStorage << 151 // computed from non-POD types. Pointers to member data should be used 213 // ******************************************* << 152 // instead. This advanced C++ feature seems not to work on earlier 214 // << 153 // versions of the same compiler. 215 template <class Type> << 216 void G4Allocator<Type>::ResetStorage() << 217 { << 218 // Clear all allocated storage and return it << 219 // 154 // 220 mem.Reset(); << 155 #if (GNU_GCC==1) && (__GNUC__==3) && (__GNUC_MINOR__>0) 221 return; << 156 Type G4AllocatorUnit<Type>::*pOffset = &G4AllocatorUnit<Type>::fElement; 222 } << 157 fUnit = (G4AllocatorUnit<Type> *) ((char *)anElement - size_t(pOffset)); >> 158 #else >> 159 fUnit = (G4AllocatorUnit<Type> *) >> 160 ((char *) anElement - offsetof(G4AllocatorUnit<Type>, fElement)); >> 161 #endif 223 162 224 // ******************************************* << 163 if (fUnit->deleted == Allocated) 225 // GetAllocatedSize << 164 { 226 // ******************************************* << 165 fUnit->deleted = Deleted; 227 // << 166 fUnit->fNext = fFreeList; 228 template <class Type> << 167 fFreeList = fUnit; 229 std::size_t G4Allocator<Type>::GetAllocatedSiz << 168 } 230 { << 231 return mem.Size(); << 232 } 169 } 233 170 234 // ******************************************* 171 // ************************************************************ 235 // GetNoPages << 172 // AddNewPage 236 // ******************************************* 173 // ************************************************************ 237 // 174 // 238 template <class Type> 175 template <class Type> 239 int G4Allocator<Type>::GetNoPages() const << 176 void G4Allocator<Type>::AddNewPage() 240 { 177 { 241 return mem.GetNoPages(); << 178 G4AllocatorPage<Type> * aPage; 242 } << 179 register G4int unit_no; 243 180 244 // ******************************************* << 181 aPage = new G4AllocatorPage<Type>; 245 // GetPageSize << 182 aPage->fNext = fPages; 246 // ******************************************* << 183 aPage->fUnits = (G4AllocatorUnit<Type> *) 247 // << 184 malloc(fPageSize); 248 template <class Type> << 185 fPages = aPage; 249 size_t G4Allocator<Type>::GetPageSize() const << 250 { << 251 return mem.GetPageSize(); << 252 } << 253 186 254 // ******************************************* << 187 for (unit_no = 0; 255 // IncreasePageSize << 188 unit_no < G4int(fPageSize/fUnitSize - 1); 256 // ******************************************* << 189 ++unit_no) 257 // << 190 { 258 template <class Type> << 191 aPage->fUnits[unit_no].fNext = &aPage->fUnits[unit_no + 1]; 259 void G4Allocator<Type>::IncreasePageSize(unsig << 192 } 260 { << 193 aPage->fUnits[unit_no].fNext = fFreeList; 261 ResetStorage(); << 194 fFreeList = &aPage->fUnits[0]; 262 mem.GrowPageSize(sz); << 263 } 195 } 264 196 265 // ******************************************* 197 // ************************************************************ 266 // GetPoolType << 198 // AddNewElement 267 // ******************************************* 199 // ************************************************************ 268 // 200 // 269 template <class Type> 201 template <class Type> 270 const char* G4Allocator<Type>::GetPoolType() c << 202 Type* G4Allocator<Type>::AddNewElement() 271 { << 272 return tname; << 273 } << 274 << 275 // ******************************************* << 276 // operator== << 277 // ******************************************* << 278 // << 279 template <class T1, class T2> << 280 bool operator==(const G4Allocator<T1>&, const << 281 { 203 { 282 return true; << 204 Type* anElement; 283 } << 284 205 285 // ******************************************* << 206 AddNewPage(); 286 // operator!= << 207 fFreeList->deleted = Allocated; 287 // ******************************************* << 208 anElement = &fFreeList->fElement; 288 // << 209 fFreeList=fFreeList->fNext; 289 template <class T1, class T2> << 210 return anElement; 290 bool operator!=(const G4Allocator<T1>&, const << 291 { << 292 return false; << 293 } 211 } 294 212 295 #endif 213 #endif 296 214