ATLAS Offline Software
ArenaHeapAllocator.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2017 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  p.linkOffset = (char*)&dummy->y - (char*)dummy;
51 
52  // Need to allow at least enough space for a pointer.
53  p.minSize = sizeof (pointer);
54 
55  return p;
56 }
57 
58 
59 /**
60  * @brief Allocate a new element.
61  *
62  * The fast path of this will be completely inlined.
63  */
64 inline
65 ArenaHeapAllocator::pointer ArenaHeapAllocator::allocate()
66 {
67  ++m_stats.elts.inuse;
68  pointer ret = m_freeptr;
69  if (ret) {
70  m_freeptr = link (ret);
71  return ret;
72  }
73  return refill();
74 }
75 
76 
77 /**
78  * @brief Free an element.
79  * @param p The element to be freed.
80  *
81  * @c clear() will be called on the element at this point,
82  * if it has been defined.
83  */
84 inline
85 void ArenaHeapAllocator::free (pointer p)
86 {
87  if (m_params.clear) {
88  m_params.clear (p);
89  }
90  link (p) = m_freeptr;
91  m_freeptr = p;
92  --m_stats.elts.inuse;
93 }
94 
95 
96 /**
97  * @brief Return a reference to the link for an element.
98  * @param p The element.
99  */
100 inline
101 ArenaHeapAllocator::pointer& ArenaHeapAllocator::link (pointer p) const
102 {
103  return *reinterpret_cast<pointer*> (p + m_params.linkOffset);
104 }
105 
106 
107 } // namespace SG
108