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 << 27 // 23 // 28 // Class Description: << 24 // $Id: G4Allocator.hh,v 1.7 2001/07/11 10:00:49 gunter Exp $ >> 25 // GEANT4 tag $Name: geant4-04-00 $ 29 // 26 // 30 // A class for fast allocation of objects to t << 27 // 31 // chunks organised as linked list. It's meant << 28 // ------------------------------------------------------------ 32 // it to the object to be allocated and defini << 29 // GEANT 4 class header file 33 // operators via MallocSingle() and FreeSingle << 34 << 35 // ---------------- G4Allocator --------- << 36 // 30 // 37 // Author: G.Cosmo (CERN), November 2000 << 31 // History: first implementation, based on object model of 38 // ------------------------------------------- << 32 // 2nd December 1995, G.Cosmo 39 #ifndef G4Allocator_hh << 33 // ---------------- G4Allocator ---------------- 40 #define G4Allocator_hh 1 << 34 // by Tim Bell, September 1995 >> 35 // ------------------------------------------------------------ >> 36 // SG, HPW: Protection vs double deletion of the same element, June 97. 41 37 42 #include <cstddef> << 38 #ifndef G4Allocator_h 43 #include <typeinfo> << 39 #define G4Allocator_h 1 44 40 45 #include "G4AllocatorPool.hh" << 41 #include <stdlib.h> >> 42 #include <stddef.h> 46 43 47 class G4AllocatorBase << 44 // G4AllocatorPage 48 { << 45 #include "G4AllocatorPage.hh" 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 46 60 template <class Type> 47 template <class Type> 61 class G4Allocator : public G4AllocatorBase << 48 class G4Allocator 62 { 49 { 63 public: << 50 G4AllocatorPage<Type> *fPages; 64 G4Allocator() throw(); << 51 G4AllocatorUnit<Type> *fFreeList; 65 ~G4Allocator() throw() override; << 52 66 // Constructor & destructor << 53 private: 67 << 54 void AddNewPage(); 68 inline Type* MallocSingle(); << 55 Type *AddNewElement(); 69 inline void FreeSingle(Type* anElement); << 56 70 // Malloc and Free methods to be used when o << 57 enum { Allocated = 0x47416C, Deleted = 0xB8BE93 }; 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 58 115 pointer allocate(size_type n, void* = nullpt << 59 public: 116 { << 60 G4Allocator(); 117 // Allocates space for n elements of type << 61 ~G4Allocator(); 118 // << 62 119 Type* mem_alloc = 0; << 63 inline Type *MallocSingle() 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 { 64 { 128 // Deallocates n elements of type Type, bu << 65 Type *anElement; 129 // << 66 130 if(n == 1) << 67 if (fFreeList != NULL) 131 FreeSingle(p); << 68 { >> 69 fFreeList->deleted = Allocated; >> 70 anElement = &fFreeList->fElement; >> 71 fFreeList = fFreeList->fNext; >> 72 } 132 else 73 else 133 ::operator delete((void*) p); << 74 anElement = AddNewElement(); 134 return; << 75 return anElement; 135 } 76 } 136 77 137 void construct(pointer p, const Type& val) { << 78 inline void FreeSingle(Type *anElement) 138 // Initialises *p by val << 139 void destroy(pointer p) { p->~Type(); } << 140 // Destroy *p but doesn't deallocate << 141 << 142 size_type max_size() const throw() << 143 { 79 { 144 // Returns the maximum number of elements << 80 G4AllocatorUnit<Type> *fUnit; 145 // << 81 146 return 2147483647 / sizeof(Type); << 82 fUnit = (G4AllocatorUnit<Type> *) >> 83 ((char *) anElement - >> 84 offsetof(G4AllocatorUnit<Type>, fElement)); >> 85 if (fUnit->deleted == Allocated) { >> 86 fUnit->deleted = Deleted; >> 87 fUnit->fNext = fFreeList; >> 88 fFreeList = fUnit; >> 89 } >> 90 /* >> 91 else if (fUnit->deleted == Deleted) { >> 92 // G4cerr << "G4Allocator : This object is already deleted" << G4endl; >> 93 } else { >> 94 // G4cerr << "G4Allocator: This object is allocated not by G4Allocator"<< G4endl; >> 95 } >> 96 */ 147 } 97 } 148 98 149 template <class U> << 150 struct rebind << 151 { << 152 using other = G4Allocator<U>; << 153 }; << 154 // Rebind allocator to type U << 155 << 156 G4AllocatorPool mem; << 157 // Pool of elements of sizeof(Type) << 158 << 159 private: << 160 const char* tname; << 161 // Type name identifier << 162 }; 99 }; 163 100 164 // ------------------------------------------- << 165 // Inline implementation << 166 // ------------------------------------------- << 167 << 168 // Initialization of the static pool << 169 // << 170 // template <class Type> G4AllocatorPool G4All << 171 101 172 // ******************************************* << 173 // G4Allocator constructor << 174 // ******************************************* << 175 // << 176 template <class Type> 102 template <class Type> 177 G4Allocator<Type>::G4Allocator() throw() << 103 G4Allocator<Type>::G4Allocator() 178 : mem(sizeof(Type)) << 179 { 104 { 180 tname = typeid(Type).name(); << 105 fPages = NULL; 181 } << 106 fFreeList = NULL; 182 << 107 AddNewPage(); 183 // ******************************************* << 184 // G4Allocator destructor << 185 // ******************************************* << 186 // << 187 template <class Type> << 188 G4Allocator<Type>::~G4Allocator() throw() = de << 189 << 190 // ******************************************* << 191 // MallocSingle << 192 // ******************************************* << 193 // << 194 template <class Type> << 195 Type* G4Allocator<Type>::MallocSingle() << 196 { << 197 return static_cast<Type*>(mem.Alloc()); << 198 } << 199 << 200 // ******************************************* << 201 // FreeSingle << 202 // ******************************************* << 203 // << 204 template <class Type> << 205 void G4Allocator<Type>::FreeSingle(Type* anEle << 206 { << 207 mem.Free(anElement); << 208 return; 108 return; 209 } 109 } 210 110 211 // ******************************************* << 212 // ResetStorage << 213 // ******************************************* << 214 // << 215 template <class Type> 111 template <class Type> 216 void G4Allocator<Type>::ResetStorage() << 112 G4Allocator<Type>::~G4Allocator() 217 { 113 { 218 // Clear all allocated storage and return it << 114 G4AllocatorPage<Type> *aPage; 219 // << 115 G4AllocatorPage<Type> *aNextPage; 220 mem.Reset(); << 116 >> 117 aPage = fPages; >> 118 while (aPage != NULL) >> 119 { >> 120 aNextPage = aPage->fNext; >> 121 free(aPage->fUnits); >> 122 delete aPage; >> 123 aPage = aNextPage; >> 124 } >> 125 fPages = NULL; >> 126 fFreeList = NULL; 221 return; 127 return; 222 } 128 } 223 129 224 // ******************************************* << 130 static const G4int G4AllocatorPageSize = 1024; 225 // GetAllocatedSize << 226 // ******************************************* << 227 // << 228 template <class Type> << 229 std::size_t G4Allocator<Type>::GetAllocatedSiz << 230 { << 231 return mem.Size(); << 232 } << 233 131 234 // ******************************************* << 235 // GetNoPages << 236 // ******************************************* << 237 // << 238 template <class Type> 132 template <class Type> 239 int G4Allocator<Type>::GetNoPages() const << 133 void G4Allocator<Type>::AddNewPage() 240 { 134 { 241 return mem.GetNoPages(); << 135 G4AllocatorPage<Type> *aPage; 242 } << 136 register G4int unit_no; 243 137 244 // ******************************************* << 138 aPage = new G4AllocatorPage<Type>; 245 // GetPageSize << 139 aPage->fNext = fPages; 246 // ******************************************* << 140 aPage->fUnits = (G4AllocatorUnit<Type> *) 247 // << 141 malloc(G4AllocatorPageSize); 248 template <class Type> << 142 fPages = aPage; 249 size_t G4Allocator<Type>::GetPageSize() const << 250 { << 251 return mem.GetPageSize(); << 252 } << 253 143 254 // ******************************************* << 144 for (unit_no = 0; 255 // IncreasePageSize << 145 unit_no < (G4AllocatorPageSize / G4int(sizeof(G4AllocatorUnit<Type>))-1); 256 // ******************************************* << 146 ++unit_no) 257 // << 147 { 258 template <class Type> << 148 aPage->fUnits[unit_no].fNext = &aPage->fUnits[unit_no + 1]; 259 void G4Allocator<Type>::IncreasePageSize(unsig << 149 } 260 { << 150 aPage->fUnits[unit_no].fNext = fFreeList; 261 ResetStorage(); << 151 fFreeList = &aPage->fUnits[0]; 262 mem.GrowPageSize(sz); << 263 } 152 } 264 153 265 // ******************************************* << 266 // GetPoolType << 267 // ******************************************* << 268 // << 269 template <class Type> 154 template <class Type> 270 const char* G4Allocator<Type>::GetPoolType() c << 155 Type *G4Allocator<Type>::AddNewElement() 271 { 156 { 272 return tname; << 157 Type *anElement; 273 } << 274 158 275 // ******************************************* << 159 AddNewPage(); 276 // operator== << 160 fFreeList->deleted = Allocated; 277 // ******************************************* << 161 anElement = &fFreeList->fElement; 278 // << 162 fFreeList=fFreeList->fNext; 279 template <class T1, class T2> << 163 return anElement; 280 bool operator==(const G4Allocator<T1>&, const << 281 { << 282 return true; << 283 } 164 } 284 165 285 // ******************************************* << 286 // operator!= << 287 // ******************************************* << 288 // << 289 template <class T1, class T2> << 290 bool operator!=(const G4Allocator<T1>&, const << 291 { << 292 return false; << 293 } << 294 166 295 #endif 167 #endif 296 168