ATLAS Offline Software
Loading...
Searching...
No Matches
ArenaHeapSTLAllocator.icc
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4/**
5 * @file AthAllocators/ArenaHeapSTLAllocator.icc
6 * @author scott snyder
7 * @date Nov 2011
8 * @brief STL-style allocator wrapper for @c ArenaHeapAllocator.
9 */
10
11
12#include <cassert>
13
14
15namespace SG {
16
17
18
19//****************************************************************************
20// Generic specialization
21//
22
23
24/**
25 * @brief Constructor.
26 * @param nblock Value to set in the parameters structure for the
27 * number of elements to allocate per block.
28 * @param name Value to set in the parameters structure for the
29 * allocator name.
30 */
31template <class T>
32ArenaHeapSTLAllocator_initParams<T>::ArenaHeapSTLAllocator_initParams
33 (size_t nblock /*= 1000*/, const std::string& name /*= ""*/)
34 : Base (nblock, name)
35{
36}
37
38
39/**
40 * @brief Return an initialized parameters structure.
41 */
42template <class T>
43ArenaAllocatorBase::Params ArenaHeapSTLAllocator_initParams<T>::params() const
44{
45 // Do the base class stuff.
46 ArenaAllocatorBase::Params p =
47 Base::operator ArenaAllocatorBase::Params();
48
49 // Disable ctor/dtor.
50 p.constructor = 0;
51 p.destructor = 0;
52
53 // Overlap link over free struct.
54 p.eltSize = std::max (sizeof(T), p.minSize);
55 p.linkOffset = 0;
56
57 return p;
58}
59
60
61/**
62 * @brief Default constructor.
63 * @param nblock Value to set in the parameters structure for the
64 * number of elements to allocate per block.
65 * @param name Value to set in the parameters structure for the
66 * allocator name.
67 */
68template <class T, class VETO>
69// cppcheck-suppress uninitMemberVar ; false positive
70ArenaHeapSTLAllocator<T, VETO>::ArenaHeapSTLAllocator
71 (size_t nblock /*= 1000*/, const std::string& name /*= ""*/)
72 : m_pool (ArenaHeapSTLAllocator_initParams<T> (nblock, name))
73{
74}
75
76
77/**
78 * @brief Copy constructor.
79 *
80 * The @c name and @c nblock parameters are copied, but the data are not.
81 */
82template <class T, class VETO>
83// cppcheck-suppress uninitMemberVar ; false positive
84ArenaHeapSTLAllocator<T, VETO>::ArenaHeapSTLAllocator
85 (const ArenaHeapSTLAllocator& a)
86 : m_pool (ArenaHeapSTLAllocator_initParams<T> (a.nblock(), a.name()))
87{
88}
89
90
91/**
92 * @brief Constructor from another @c ArenaHeapSTLAllocator.
93 *
94 * The @c name and @c nblock parameters are copied, but the data are not.
95 */
96template <class T, class VETO>
97template <class U, class V>
98// cppcheck-suppress uninitMemberVar ; false positive
99ArenaHeapSTLAllocator<T, VETO>::ArenaHeapSTLAllocator
100 (const ArenaHeapSTLAllocator<U, V>& a)
101 : m_pool (ArenaHeapSTLAllocator_initParams<T> (a.nblock(), a.name()))
102{
103}
104
105
106/**
107 * @brief Move constructor.
108 *
109 * Move the data.
110 */
111template <class T, class VETO>
112ArenaHeapSTLAllocator<T, VETO>::ArenaHeapSTLAllocator
113 (ArenaHeapSTLAllocator&& a)
114 : m_pool (std::move (a.m_pool))
115{
116}
117
118
119/**
120 * @brief Move constructor.
121 *
122 * Move the data.
123 */
124template <class T, class VETO>
125ArenaHeapSTLAllocator<T, VETO>&
126ArenaHeapSTLAllocator<T, VETO>::operator= (ArenaHeapSTLAllocator&& a)
127{
128 if (this != &a) {
129 m_pool = std::move (a.m_pool);
130 }
131 return *this;
132}
133
134
135/**
136 * @brief Swap.
137 */
138template <class T, class VETO>
139void ArenaHeapSTLAllocator<T, VETO>::swap (ArenaHeapSTLAllocator& a)
140{
141 m_pool.swap (a.m_pool);
142}
143
144
145/**
146 * @brief Equality test.
147 *
148 * Two allocators should compare equal if objects allocated by one
149 * can be deallocated by the other. We should just check if they
150 * are the same object.
151 */
152template <class T, class VETO>
153inline
154bool ArenaHeapSTLAllocator<T, VETO>::operator==
155 (const ArenaHeapSTLAllocator& other) const
156{
157 return this == &other;
158}
159
160
161/**
162 * @brief Inequality test.
163 *
164 * Two allocators should compare equal if objects allocated by one
165 * can be deallocated by the other. We should just check if they
166 * are the same object.
167 */
168template <class T, class VETO>
169inline
170bool ArenaHeapSTLAllocator<T, VETO>::operator!=
171 (const ArenaHeapSTLAllocator& other) const
172{
173 return this != &other;
174}
175
176
177/**
178 * @brief Return allocator to use for a copy-constructed container.
179 *
180 * When we copy-construct a container, we want the new allocator
181 * to copy parameters from the old one, but not the data.
182 */
183template <class T, class VETO>
184inline
185ArenaHeapSTLAllocator<T, VETO>
186ArenaHeapSTLAllocator<T, VETO>::select_on_container_copy_construction() const
187{
188 return ArenaHeapSTLAllocator (nblock(), name());
189}
190
191
192/**
193 * @brief Convert a reference to an address.
194 */
195template <class T, class VETO>
196inline
197typename ArenaHeapSTLAllocator<T, VETO>::pointer
198ArenaHeapSTLAllocator<T, VETO>::address (reference x) const
199{
200 return &x;
201}
202
203
204/**
205 * @brief Allocate new objects.
206 * @param n Number of objects to allocate. Must be 1.
207 * @param hint Allocation hint. Not used.
208 */
209template <class T, class VETO>
210inline
211typename ArenaHeapSTLAllocator<T, VETO>::pointer
212ArenaHeapSTLAllocator<T, VETO>::allocate (size_type
213#ifndef NDEBUG
214 n
215#endif
216 , const void* /*hint = 0*/)
217{
218 assert (n == 1);
219 return reinterpret_cast<pointer> (m_pool.allocate());
220}
221
222
223/**
224 * @brief Deallocate objects.
225 * @param n Number of objects to deallocate. Must be 1.
226 *
227 * This implementation doesn't do anything.
228 */
229template <class T, class VETO>
230inline
231void ArenaHeapSTLAllocator<T, VETO>::deallocate (pointer p, size_type
232#ifndef NDEBUG
233 n
234#endif
235 )
236{
237 assert (n == 1);
238 using pointer_nc = std::remove_const_t<T>*;
239 pointer_nc pp ATLAS_THREAD_SAFE = const_cast<pointer_nc>(p);
240 m_pool.free (reinterpret_cast<ArenaHeapAllocator::pointer> (pp));
241}
242
243
244/**
245 * @brief Return the maximum number of objects we can allocate at once.
246 *
247 * This always returns 1.
248 */
249template <class T, class VETO>
250inline
251typename ArenaHeapSTLAllocator<T, VETO>::size_type
252ArenaHeapSTLAllocator<T, VETO>::max_size() const throw()
253{
254 return 1;
255}
256
257
258/**
259 * @brief Call the @c T constructor.
260 * @param p Location of the memory.
261 * @param args Arguments to pass to the constructor.
262 */
263template <class T, class VETO>
264template <class... Args>
265inline
266void ArenaHeapSTLAllocator<T, VETO>::construct (pointer p, Args&&... args)
267{
268 new (p) T(std::forward<Args>(args)...);
269}
270
271
272/**
273 * @brief Call the @c T destructor.
274 * @param p Location of the memory.
275 */
276template <class T, class VETO>
277inline
278void ArenaHeapSTLAllocator<T, VETO>::destroy (pointer p)
279{
280 p->~T();
281}
282
283
284/**
285 * @brief Return the hinted number of objects allocated per block.
286 */
287template <class T, class VETO>
288inline
289size_t ArenaHeapSTLAllocator<T, VETO>::nblock() const
290{
291 return m_pool.params().nblock;
292}
293
294
295/**
296 * @brief Return the name of this allocator.
297 */
298template <class T, class VETO>
299inline
300const std::string& ArenaHeapSTLAllocator<T, VETO>::name() const
301{
302 return m_pool.name();
303}
304
305
306/**
307 * @brief Free all allocated elements.
308 *
309 * All elements allocated are returned to the free state.
310 * @c clear should be called on them if it was provided.
311 * The elements may continue to be cached internally, without
312 * returning to the system.
313 */
314template <class T, class VETO>
315void ArenaHeapSTLAllocator<T, VETO>::reset()
316{
317 m_pool.reset();
318}
319
320
321/**
322 * @brief Free all allocated elements and release memory back to the system.
323 *
324 * All elements allocated are freed, and all allocated blocks of memory
325 * are released back to the system.
326 * @c destructor should be called on them if it was provided
327 * (preceded by @c clear if provided and @c mustClear was set).
328 */
329template <class T, class VETO>
330void ArenaHeapSTLAllocator<T, VETO>::erase()
331{
332 m_pool.erase();
333}
334
335
336/**
337 * @brief Set the total number of elements cached by the allocator.
338 * @param size The desired pool size.
339 *
340 * This allows changing the number of elements that are currently free
341 * but cached. Any allocated elements are not affected by this call.
342 *
343 * If @c size is greater than the total number of elements currently
344 * cached, then more will be allocated. This will preferably done
345 * with a single block, but that is not guaranteed; in addition, the
346 * allocator may allocate more elements than is requested.
347 *
348 * If @c size is smaller than the total number of elements currently
349 * cached, as many blocks as possible will be released back to the system.
350 * It may not be possible to release the number of elements requested;
351 * this should be implemented on a best-effort basis.
352 */
353template <class T, class VETO>
354void ArenaHeapSTLAllocator<T, VETO>::reserve (size_t size)
355{
356 m_pool.reserve (size);
357}
358
359
360/**
361 * @brief Return the statistics block for this allocator.
362 */
363template <class T, class VETO>
364ArenaAllocatorBase::Stats ArenaHeapSTLAllocator<T, VETO>::stats() const
365{
366 return m_pool.stats();
367}
368
369
370/**
371 * @brief Return a pointer to the underlying allocator (may be 0).
372 */
373template <class T, class VETO>
374const ArenaBlockAllocatorBase* ArenaHeapSTLAllocator<T, VETO>::poolptr() const
375{
376 return &m_pool;
377}
378
379
380/**
381 * @brief Write-protect the memory managed by this allocator.
382 *
383 * Adjust protection on the memory managed by this allocator
384 * to disallow writes.
385 */
386template <class T, class VETO>
387inline
388void ArenaHeapSTLAllocator<T, VETO>::protect()
389{
390 m_pool.protect();
391}
392
393
394/**
395 * @brief Write-enable the memory managed by this allocator.
396 *
397 * Adjust protection on the memory managed by this allocator
398 * to allow writes.
399 */
400template <class T, class VETO>
401inline
402void ArenaHeapSTLAllocator<T, VETO>::unprotect()
403{
404 m_pool.unprotect();
405}
406
407
408//****************************************************************************
409// Vetoed specialization.
410//
411
412
413/**
414 * @brief Default constructor.
415 * @param nblock Value to set in the parameters structure for the
416 * number of elements to allocate per block.
417 * @param name Value to set in the parameters structure for the
418 * allocator name.
419 */
420template <class T>
421// cppcheck-suppress uninitMemberVar ; false positive
422ArenaHeapSTLAllocator<T, T>::ArenaHeapSTLAllocator
423 (size_t nblock /*= 1000*/, const std::string& name /*= ""*/)
424 : m_nblock (nblock),
425 m_name (name),
426 m_poolptr (0)
427{
428}
429
430
431/**
432 * @brief Constructor from another @c ArenaHeapSTLAllocator.
433 *
434 * The @c name and @c nblock parameters are copied, but the data are not.
435 */
436template <class T>
437template <class U, class V>
438// cppcheck-suppress uninitMemberVar ; false positive
439ArenaHeapSTLAllocator<T, T>::ArenaHeapSTLAllocator
440 (const ArenaHeapSTLAllocator<U, V>& a)
441 : m_nblock (a.nblock()),
442 m_name (a.name()),
443 m_poolptr (a.poolptr())
444{
445}
446
447
448/**
449 * @brief Return the hinted number of objects allocated per block.
450 */
451template <class T>
452inline
453size_t ArenaHeapSTLAllocator<T, T>::nblock() const
454{
455 return m_nblock;
456}
457
458
459/**
460 * @brief Return the name of this allocator.
461 */
462template <class T>
463inline
464const std::string& ArenaHeapSTLAllocator<T, T>::name() const
465{
466 return m_name;
467}
468
469
470/**
471 * @brief Return the statistics block for this allocator.
472 */
473template <class T>
474ArenaAllocatorBase::Stats
475ArenaHeapSTLAllocator<T, T>::stats() const
476{
477 if (m_poolptr)
478 return m_poolptr->stats();
479 return ArenaAllocatorBase::Stats();
480}
481
482
483/**
484 * @brief Return a pointer to the underlying allocator (may be 0).
485 */
486template <class T>
487const ArenaBlockAllocatorBase* ArenaHeapSTLAllocator<T, T>::poolptr() const
488{
489 return m_poolptr;
490}
491
492
493//****************************************************************************
494// Non-const variant.
495//
496
497
498/**
499 * @brief Constructor.
500 * @param a Allocator to reference.
501 * @param poolptr_nc Non-const pointer to the underlying allocator.
502 */
503template <class T>
504template <class U, class V>
505ArenaNonConstHeapSTLAllocator<T>::ArenaNonConstHeapSTLAllocator
506 (const ArenaHeapSTLAllocator<U, V>& a,
507 ArenaBlockAllocatorBase* poolptr_nc)
508 : ArenaHeapSTLAllocator<T, T>(a),
509 m_poolptr_nc (poolptr_nc)
510{
511}
512
513
514/**
515 * @brief Free all allocated elements.
516 *
517 * All elements allocated are returned to the free state.
518 * @c clear should be called on them if it was provided.
519 * The elements may continue to be cached internally, without
520 * returning to the system.
521 */
522template <class T>
523void ArenaNonConstHeapSTLAllocator<T>::reset()
524{
525 if (m_poolptr_nc)
526 m_poolptr_nc->reset();
527}
528
529
530/**
531 * @brief Free all allocated elements and release memory back to the system.
532 *
533 * All elements allocated are freed, and all allocated blocks of memory
534 * are released back to the system.
535 * @c destructor should be called on them if it was provided
536 * (preceded by @c clear if provided and @c mustClear was set).
537 */
538template <class T>
539void ArenaNonConstHeapSTLAllocator<T>::erase()
540{
541 if (m_poolptr_nc)
542 m_poolptr_nc->erase();
543}
544
545
546/**
547 * @brief Set the total number of elements cached by the allocator.
548 * @param size The desired pool size.
549 *
550 * This allows changing the number of elements that are currently free
551 * but cached. Any allocated elements are not affected by this call.
552 *
553 * If @c size is greater than the total number of elements currently
554 * cached, then more will be allocated. This will preferably done
555 * with a single block, but that is not guaranteed; in addition, the
556 * allocator may allocate more elements than is requested.
557 *
558 * If @c size is smaller than the total number of elements currently
559 * cached, as many blocks as possible will be released back to the system.
560 * It may not be possible to release the number of elements requested;
561 * this should be implemented on a best-effort basis.
562 */
563template <class T>
564void ArenaNonConstHeapSTLAllocator<T>::reserve (size_t size)
565{
566 if (m_poolptr_nc)
567 m_poolptr_nc->reserve (size);
568}
569
570
571/**
572 * @brief Write-protect the memory managed by this allocator.
573 *
574 * Adjust protection on the memory managed by this allocator
575 * to disallow writes.
576 */
577template <class T>
578inline
579void ArenaNonConstHeapSTLAllocator<T>::protect()
580{
581 if (m_poolptr_nc)
582 m_poolptr_nc->protect();
583}
584
585
586/**
587 * @brief Write-enable the memory managed by this allocator.
588 *
589 * Adjust protection on the memory managed by this allocator
590 * to allow writes.
591 */
592template <class T>
593inline
594void ArenaNonConstHeapSTLAllocator<T>::unprotect()
595{
596 if (m_poolptr_nc)
597 m_poolptr_nc->unprotect();
598}
599
600
601/**
602 * @brief Return an allocator supporting non-const methods from
603 * a non-const container reference.
604 * @param c The (non-const) container.
605 */
606template <class T>
607template <class CONT>
608ArenaNonConstHeapSTLAllocator<T>
609ArenaHeapSTLAllocator<T, T>::get_allocator ATLAS_NOT_CONST_THREAD_SAFE (CONT& c)
610{
611 // Must be called with a non-const object.
612 typename std::remove_const<CONT>::type& cc = c;
613 ArenaHeapSTLAllocator<T, T> a (cc.get_allocator());
614 return ArenaNonConstHeapSTLAllocator<T> (a,
615 const_cast<ArenaBlockAllocatorBase*>(a.poolptr()));
616}
617
618
619/**
620 * @brief Hook for unprotecting an arena.
621 *
622 * Sometimes we need to ensure that an arena is unprotected before we start
623 * destroying an object that contains the arena. To do that without
624 * making assumptions about whether the arena supports an unprotect
625 * operation, call this function.
626 */
627template <class T, class VETO>
628void maybeUnprotect (ArenaHeapSTLAllocator<T, VETO>& a)
629{
630 a.unprotect();
631}
632
633
634} // namespace SG