Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 // G4Allocator 27 // 28 // Class Description: 29 // 30 // A class for fast allocation of objects to the heap through a pool of 31 // chunks organised as linked list. It's meant to be used by associating 32 // it to the object to be allocated and defining for it new and delete 33 // operators via MallocSingle() and FreeSingle() methods. 34 35 // ---------------- G4Allocator ---------------- 36 // 37 // Author: G.Cosmo (CERN), November 2000 38 // -------------------------------------------------------------------- 39 #ifndef G4Allocator_hh 40 #define G4Allocator_hh 1 41 42 #include <cstddef> 43 #include <typeinfo> 44 45 #include "G4AllocatorPool.hh" 46 47 class G4AllocatorBase 48 { 49 public: 50 G4AllocatorBase(); 51 virtual ~G4AllocatorBase() = default; 52 virtual void ResetStorage() = 0; 53 virtual std::size_t GetAllocatedSize() const = 0; 54 virtual int GetNoPages() const = 0; 55 virtual std::size_t GetPageSize() const = 0; 56 virtual void IncreasePageSize(unsigned int sz) = 0; 57 virtual const char* GetPoolType() const = 0; 58 }; 59 60 template <class Type> 61 class G4Allocator : public G4AllocatorBase 62 { 63 public: 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 overloading 71 // new and delete operators in the client <Type> object 72 73 inline void ResetStorage() override; 74 // Returns allocated storage to the free store, resets allocator. 75 // Note: contents in memory are lost using this call ! 76 77 inline std::size_t GetAllocatedSize() const override; 78 // Returns the size of the total memory allocated 79 inline int GetNoPages() const override; 80 // Returns the total number of allocated pages 81 inline std::size_t GetPageSize() const override; 82 // Returns the current size of a page 83 inline void IncreasePageSize(unsigned int sz) override; 84 // Resets allocator and increases default page size of a given factor 85 86 inline const char* GetPoolType() const override; 87 // Returns the type_info Id of the allocated type in the pool 88 89 // This public section includes standard methods and types 90 // required if the allocator is to be used as alternative 91 // allocator for STL containers. 92 // NOTE: the code below is a trivial implementation to make 93 // this class an STL compliant allocator. 94 // It is anyhow NOT recommended to use this class as 95 // alternative allocator for STL containers ! 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) throw() 107 : mem(right.mem) 108 {} 109 // Copy constructor 110 111 pointer address(reference r) const { return &r; } 112 const_pointer address(const_reference r) const { return &r; } 113 // Returns the address of values 114 115 pointer allocate(size_type n, void* = nullptr) 116 { 117 // Allocates space for n elements of type Type, but does not initialise 118 // 119 Type* mem_alloc = 0; 120 if(n == 1) 121 mem_alloc = MallocSingle(); 122 else 123 mem_alloc = static_cast<Type*>(::operator new(n * sizeof(Type))); 124 return mem_alloc; 125 } 126 void deallocate(pointer p, size_type n) 127 { 128 // Deallocates n elements of type Type, but doesn't destroy 129 // 130 if(n == 1) 131 FreeSingle(p); 132 else 133 ::operator delete((void*) p); 134 return; 135 } 136 137 void construct(pointer p, const Type& val) { new((void*) p) Type(val); } 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 { 144 // Returns the maximum number of elements that can be allocated 145 // 146 return 2147483647 / sizeof(Type); 147 } 148 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 }; 163 164 // ------------------------------------------------------------ 165 // Inline implementation 166 // ------------------------------------------------------------ 167 168 // Initialization of the static pool 169 // 170 // template <class Type> G4AllocatorPool G4Allocator<Type>::mem(sizeof(Type)); 171 172 // ************************************************************ 173 // G4Allocator constructor 174 // ************************************************************ 175 // 176 template <class Type> 177 G4Allocator<Type>::G4Allocator() throw() 178 : mem(sizeof(Type)) 179 { 180 tname = typeid(Type).name(); 181 } 182 183 // ************************************************************ 184 // G4Allocator destructor 185 // ************************************************************ 186 // 187 template <class Type> 188 G4Allocator<Type>::~G4Allocator() throw() = default; 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* anElement) 206 { 207 mem.Free(anElement); 208 return; 209 } 210 211 // ************************************************************ 212 // ResetStorage 213 // ************************************************************ 214 // 215 template <class Type> 216 void G4Allocator<Type>::ResetStorage() 217 { 218 // Clear all allocated storage and return it to the free store 219 // 220 mem.Reset(); 221 return; 222 } 223 224 // ************************************************************ 225 // GetAllocatedSize 226 // ************************************************************ 227 // 228 template <class Type> 229 std::size_t G4Allocator<Type>::GetAllocatedSize() const 230 { 231 return mem.Size(); 232 } 233 234 // ************************************************************ 235 // GetNoPages 236 // ************************************************************ 237 // 238 template <class Type> 239 int G4Allocator<Type>::GetNoPages() const 240 { 241 return mem.GetNoPages(); 242 } 243 244 // ************************************************************ 245 // GetPageSize 246 // ************************************************************ 247 // 248 template <class Type> 249 size_t G4Allocator<Type>::GetPageSize() const 250 { 251 return mem.GetPageSize(); 252 } 253 254 // ************************************************************ 255 // IncreasePageSize 256 // ************************************************************ 257 // 258 template <class Type> 259 void G4Allocator<Type>::IncreasePageSize(unsigned int sz) 260 { 261 ResetStorage(); 262 mem.GrowPageSize(sz); 263 } 264 265 // ************************************************************ 266 // GetPoolType 267 // ************************************************************ 268 // 269 template <class Type> 270 const char* G4Allocator<Type>::GetPoolType() const 271 { 272 return tname; 273 } 274 275 // ************************************************************ 276 // operator== 277 // ************************************************************ 278 // 279 template <class T1, class T2> 280 bool operator==(const G4Allocator<T1>&, const G4Allocator<T2>&) throw() 281 { 282 return true; 283 } 284 285 // ************************************************************ 286 // operator!= 287 // ************************************************************ 288 // 289 template <class T1, class T2> 290 bool operator!=(const G4Allocator<T1>&, const G4Allocator<T2>&) throw() 291 { 292 return false; 293 } 294 295 #endif 296