Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
TaskAllocator.hh
Go to the documentation of this file.
1//
2// MIT License
3// Copyright (c) 2020 Jonathan R. Madsen
4// Permission is hereby granted, free of charge, to any person obtaining a copy
5// of this software and associated documentation files (the "Software"), to deal
6// in the Software without restriction, including without limitation the rights
7// to use, copy, modify, merge, publish, distribute, sublicense, and
8// copies of the Software, and to permit persons to whom the Software is
9// furnished to do so, subject to the following conditions:
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED
12// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
13// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
15// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
16// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
17// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18//
19//
20// ------------------------------------------------------------
21// Tasking class header file
22//
23// Class Description:
24//
25// A class for fast allocation of objects to the heap through a pool of
26// chunks organised as linked list. It's meant to be used by associating
27// it to the object to be allocated and defining for it new and delete
28// operators via MallocSingle() and FreeSingle() methods.
29// ---------------- TaskAllocator ----------------
30//
31// ------------------------------------------------------------
32
33#pragma once
34
35#include <cstddef>
36#include <typeinfo>
37
39#include "PTL/Threading.hh"
40
41namespace PTL
42{
43//--------------------------------------------------------------------------------------//
44
46{
47public:
49 virtual ~TaskAllocatorBase();
50 virtual void ResetStorage() = 0;
51 virtual size_t GetAllocatedSize() const = 0;
52 virtual int GetNoPages() const = 0;
53 virtual size_t GetPageSize() const = 0;
54 virtual void IncreasePageSize(unsigned int sz) = 0;
55 virtual const char* GetPoolType() const = 0;
56};
57
58//--------------------------------------------------------------------------------------//
59
60template <class Type>
62{
63public: // with description
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 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 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 inline const char* GetPoolType() const override;
86 // Returns the type_info Id of the allocated type in the pool
87
88public: // without description
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
98 typedef size_t size_type;
99 typedef ptrdiff_t difference_type;
100 typedef Type* pointer;
101 typedef const Type* const_pointer;
102 typedef Type& reference;
103 typedef const Type& const_reference;
104
105 template <class U>
107 : mem(right.mem)
108 , tname(right.name())
109 {}
110 // Copy constructor
111
112 pointer address(reference r) const { return &r; }
113 const_pointer address(const_reference r) const { return &r; }
114 // Returns the address of values
115
117 {
118 // Allocates space for n elements of type Type, but does not initialise
119 //
120 Type* mem_alloc = 0;
121 if(n == 1)
122 mem_alloc = MallocSingle();
123 else
124 mem_alloc = static_cast<Type*>(::operator new(n * sizeof(Type)));
125 return mem_alloc;
126 }
128 {
129 // Deallocates n elements of type Type, but doesn't destroy
130 //
131 if(n == 1)
132 FreeSingle(p);
133 else
134 ::operator delete((void*) p);
135 return;
136 }
137
138 void construct(pointer p, const Type& val) { new((void*) p) Type(val); }
139 // Initialises *p by val
140 void destroy(pointer p) { p->~Type(); }
141 // Destroy *p but doesn't deallocate
142
143 size_type max_size() const throw()
144 {
145 // Returns the maximum number of elements that can be allocated
146 //
147 return 2147483647 / sizeof(Type);
148 }
149
150 template <class U>
151 struct rebind
152 {
154 };
155 // Rebind allocator to type U
156
158 // Pool of elements of sizeof(Type)
159
160private:
161 const char* tname;
162 // Type name identifier
163};
164
165//--------------------------------------------------------------------------------------//
166//
167// Inherit from this class, e.g. MyClass : public TaskAllocator<MyClass>
168//
169//--------------------------------------------------------------------------------------//
170
171template <typename Type>
173{
174public:
176 typedef size_t size_type;
177 typedef ptrdiff_t difference_type;
178 typedef Type* pointer;
179 typedef const Type* const_pointer;
180 typedef Type& reference;
181 typedef const Type& const_reference;
183
184public:
185 // define the new operator
186 void* operator new(size_type)
187 {
188 return static_cast<void*>(get_allocator()->MallocSingle());
189 }
190 // define the delete operator
191 void operator delete(void* ptr)
192 {
193 get_allocator()->FreeSingle(static_cast<pointer>(ptr));
194 }
195
196private:
197 // currently disabled due to memory leak found via -fsanitize=leak
198 // static function to get allocator
199 static allocator_type* get_allocator()
200 {
201 typedef std::unique_ptr<allocator_type> allocator_ptr;
202 static thread_local allocator_ptr _allocator = allocator_ptr(new allocator_type);
203 return _allocator.get();
204 }
205};
206
207//--------------------------------------------------------------------------------------//
208// Inline implementation
209
210template <class Type>
212: mem(sizeof(Type))
213, tname(typeid(Type).name())
214{}
215
216// ************************************************************
217// TaskAllocatorImpl destructor
218// ************************************************************
219//
220template <class Type>
222{}
223
224// ************************************************************
225// MallocSingle
226// ************************************************************
227//
228template <class Type>
229Type*
231{
232 return static_cast<Type*>(mem.Alloc());
233}
234
235// ************************************************************
236// FreeSingle
237// ************************************************************
238//
239template <class Type>
240void
242{
243 mem.Free(anElement);
244 return;
245}
246
247// ************************************************************
248// ResetStorage
249// ************************************************************
250//
251template <class Type>
252void
254{
255 // Clear all allocated storage and return it to the free store
256 //
257 mem.Reset();
258 return;
259}
260
261// ************************************************************
262// GetAllocatedSize
263// ************************************************************
264//
265template <class Type>
266size_t
268{
269 return mem.Size();
270}
271
272// ************************************************************
273// GetNoPages
274// ************************************************************
275//
276template <class Type>
277int
279{
280 return mem.GetNoPages();
281}
282
283// ************************************************************
284// GetPageSize
285// ************************************************************
286//
287template <class Type>
288size_t
290{
291 return mem.GetPageSize();
292}
293
294// ************************************************************
295// IncreasePageSize
296// ************************************************************
297//
298template <class Type>
299void
301{
302 ResetStorage();
303 mem.GrowPageSize(sz);
304}
305
306// ************************************************************
307// GetPoolType
308// ************************************************************
309//
310template <class Type>
311const char*
313{
314 return tname;
315}
316
317// ************************************************************
318// operator==
319// ************************************************************
320//
321template <class T1, class T2>
322bool
324{
325 return true;
326}
327
328// ************************************************************
329// operator!=
330// ************************************************************
331//
332template <class T1, class T2>
333bool
335{
336 return false;
337}
338
339} // namespace PTL
G4ProfileType Type
virtual void IncreasePageSize(unsigned int sz)=0
virtual void ResetStorage()=0
virtual size_t GetAllocatedSize() const =0
virtual const char * GetPoolType() const =0
virtual size_t GetPageSize() const =0
virtual int GetNoPages() const =0
void construct(pointer p, const Type &val)
void destroy(pointer p)
void ResetStorage() override
size_type max_size() const
const char * GetPoolType() const override
TaskAllocatorImpl(const TaskAllocatorImpl< U > &right)
const Type * const_pointer
const Type & const_reference
size_t GetPageSize() const override
pointer allocate(size_type n, void *=0)
size_t GetAllocatedSize() const override
const_pointer address(const_reference r) const
int GetNoPages() const override
void IncreasePageSize(unsigned int sz) override
TaskAllocatorPool mem
pointer address(reference r) const
void FreeSingle(Type *anElement)
void deallocate(pointer p, size_type n)
TaskAllocatorImpl< Type > allocator_type
ptrdiff_t difference_type
const Type & const_reference
const Type * const_pointer
Definition: AutoLock.hh:254
bool operator==(const TaskAllocatorImpl< T1 > &, const TaskAllocatorImpl< T2 > &)
bool operator!=(const TaskAllocatorImpl< T1 > &, const TaskAllocatorImpl< T2 > &)
TaskAllocatorImpl< U > other