ATLAS Offline Software
ArenaHeapAllocator.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // $Id: ArenaHeapAllocator.icc 470529 2011-11-24 23:54:22Z ssnyder $
6 /**
7  * @file AthAllocators/ArenaPoolAllocator.icc
8  * @author scott snyder
9  * @date May 2007
10  * @brief Heap-based allocator.
11  * Inline and template implementations.
12  */
13 
14 
15 namespace SG {
16 
17 
18 /**
19  * @brief Constructor for parameters helper.
20  * @param nblock Value to set in the parameters structure for the
21  * number of elements to allocate per block.
22  * @param name Value to set in the parameters structure for the
23  * allocator name.
24  */
25 template <typename T, bool clear, bool no_ctor, bool no_dtor>
26 ArenaHeapAllocator::initParams<T, clear, no_ctor, no_dtor>::
27 initParams (size_t nblock /*=1000*/, const std::string& name /*=""*/)
28  : Base (nblock, name)
29 {
30 }
31 
32 
33 /**
34  * @brief Return an initialized parameters structure.
35  */
36 template <typename T, bool clear, bool no_ctor, bool no_dtor>
37 ArenaAllocatorBase::Params
38 ArenaHeapAllocator::initParams<T, clear, no_ctor, no_dtor>::params() const
39 {
40  // Do the base class stuff.
41  Params p = Base::operator ArenaAllocatorBase::Params();
42 
43  // Allow space for an extra pointer.
44  struct Dummy {
45  T x;
46  pointer y;
47  };
48  p.eltSize = sizeof (Dummy);
49  Dummy* dummy = (Dummy*)0x1234;
50  // nb. offsetof gives warnings here because the struct is not standard-layout.
51  p.linkOffset = reinterpret_cast<char*>(&dummy->y) - reinterpret_cast<char*>(dummy);
52 
53  // Need to allow at least enough space for a pointer.
54  p.minSize = sizeof (pointer);
55 
56  return p;
57 }
58 
59 
60 /**
61  * @brief Allocate a new element.
62  *
63  * The fast path of this will be completely inlined.
64  */
65 inline
66 ArenaHeapAllocator::pointer ArenaHeapAllocator::allocate()
67 {
68  ++m_stats.elts.inuse;
69  pointer ret = m_freeptr;
70  if (ret) {
71  m_freeptr = link (ret);
72  return ret;
73  }
74  return refill();
75 }
76 
77 
78 /**
79  * @brief Free an element.
80  * @param p The element to be freed.
81  *
82  * @c clear() will be called on the element at this point,
83  * if it has been defined.
84  */
85 inline
86 void ArenaHeapAllocator::free (pointer p)
87 {
88  if (m_params.clear) {
89  m_params.clear (p);
90  }
91  link (p) = m_freeptr;
92  m_freeptr = p;
93  --m_stats.elts.inuse;
94 }
95 
96 
97 /**
98  * @brief Return a reference to the link for an element.
99  * @param p The element.
100  */
101 inline
102 ArenaHeapAllocator::pointer& ArenaHeapAllocator::link (pointer p) const
103 {
104  return *reinterpret_cast<pointer*> (p + m_params.linkOffset);
105 }
106 
107 
108 } // namespace SG
109