heap_based_pool_allocator.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Pavel Kirienko <pavel.kirienko@gmail.com>
3  */
4 
5 #ifndef UAVCAN_HELPERS_HEAP_BASED_POOL_ALLOCATOR_HPP_INCLUDED
6 #define UAVCAN_HELPERS_HEAP_BASED_POOL_ALLOCATOR_HPP_INCLUDED
7 
8 #include <cstdlib>
10 #include <uavcan/debug.hpp>
12 
13 namespace uavcan
14 {
38 template <std::size_t BlockSize,
39  typename RaiiSynchronizer = char>
42 {
43  union Node
44  {
46  private:
47  uint8_t data[BlockSize];
48  long double _aligner1;
49  long long _aligner2;
50  };
51 
54 
57 
59 
60 public:
70  HeapBasedPoolAllocator(uint16_t block_capacity_soft_limit,
71  uint16_t block_capacity_hard_limit = 0) :
72  capacity_soft_limit_(block_capacity_soft_limit),
73  capacity_hard_limit_((block_capacity_hard_limit > 0) ? block_capacity_hard_limit :
74  static_cast<uint16_t>(min(static_cast<uint32_t>(block_capacity_soft_limit) * 2U,
75  static_cast<uint32_t>(NumericTraits<uint16_t>::max())))),
76  num_reserved_blocks_(0),
77  num_allocated_blocks_(0),
78  reserve_(UAVCAN_NULLPTR)
79  { }
80 
86  {
87  shrink();
88 #if UAVCAN_DEBUG
89  if (num_allocated_blocks_ > 0)
90  {
91  UAVCAN_TRACE("HeapBasedPoolAllocator", "%u BLOCKS LEAKED", num_allocated_blocks_);
92  }
93 #endif
94  }
95 
100  virtual void* allocate(std::size_t size)
101  {
102  if (size > BlockSize)
103  {
104  return UAVCAN_NULLPTR;
105  }
106 
107  {
108  RaiiSynchronizer lock;
109  (void)lock;
110 
111  Node* const p = reserve_;
112 
113  if (UAVCAN_LIKELY(p != UAVCAN_NULLPTR))
114  {
115  reserve_ = reserve_->next;
116  num_allocated_blocks_++;
117  return p;
118  }
119 
120  if (num_reserved_blocks_ >= capacity_hard_limit_) // Hard limit reached, no further allocations
121  {
122  return UAVCAN_NULLPTR;
123  }
124  }
125 
126  // Unlikely branch
127  void* const m = std::malloc(sizeof(Node));
128  if (m != UAVCAN_NULLPTR)
129  {
130  RaiiSynchronizer lock;
131  (void)lock;
132 
133  num_reserved_blocks_++;
134  num_allocated_blocks_++;
135  }
136  return m;
137  }
138 
143  virtual void deallocate(const void* ptr)
144  {
145  if (ptr != UAVCAN_NULLPTR)
146  {
147  RaiiSynchronizer lock;
148  (void)lock;
149 
150  Node* const node = static_cast<Node*>(const_cast<void*>(ptr));
151  node->next = reserve_;
152  reserve_ = node;
153 
154  num_allocated_blocks_--;
155  }
156  }
157 
161  virtual uint16_t getBlockCapacity() const { return capacity_soft_limit_; }
162 
166  uint16_t getBlockCapacityHardLimit() const { return capacity_hard_limit_; }
167 
172  void shrink()
173  {
174  Node* p = UAVCAN_NULLPTR;
175  for (;;)
176  {
177  {
178  RaiiSynchronizer lock;
179  (void)lock;
180  // Removing from reserve and updating the counter.
181  p = reserve_;
182  if (p != UAVCAN_NULLPTR)
183  {
184  reserve_ = reserve_->next;
185  num_reserved_blocks_--;
186  }
187  else
188  {
189  break;
190  }
191  }
192  // Then freeing, having left the critical section.
193  std::free(p);
194  }
195  }
196 
201  {
202  RaiiSynchronizer lock;
203  (void)lock;
204  return num_allocated_blocks_;
205  }
206 
211  {
212  RaiiSynchronizer lock;
213  (void)lock;
214  return num_reserved_blocks_;
215  }
216 };
217 
218 }
219 
220 #endif
UAVCAN_NULLPTR
#define UAVCAN_NULLPTR
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:51
uavcan::Noncopyable
Definition: templates.hpp:46
std::size_t
unsigned long size_t
Definition: coverity_scan_model.cpp:19
debug.hpp
uavcan::uint32_t
std::uint32_t uint32_t
Definition: std.hpp:26
uavcan::HeapBasedPoolAllocator::Node::_aligner1
long double _aligner1
Definition: heap_based_pool_allocator.hpp:48
uavcan::HeapBasedPoolAllocator::reserve_
Node * reserve_
Definition: heap_based_pool_allocator.hpp:58
uavcan::HeapBasedPoolAllocator::capacity_hard_limit_
const uint16_t capacity_hard_limit_
Definition: heap_based_pool_allocator.hpp:53
dynamic_memory.hpp
uavcan::HeapBasedPoolAllocator::Node::_aligner2
long long _aligner2
Definition: heap_based_pool_allocator.hpp:49
uavcan::HeapBasedPoolAllocator::getNumReservedBlocks
uint16_t getNumReservedBlocks() const
Definition: heap_based_pool_allocator.hpp:210
UAVCAN_TRACE
#define UAVCAN_TRACE(...)
Definition: libuavcan/libuavcan/include/uavcan/debug.hpp:31
uavcan::HeapBasedPoolAllocator::Node
Definition: heap_based_pool_allocator.hpp:43
uavcan::uint16_t
std::uint16_t uint16_t
Definition: std.hpp:25
uavcan::HeapBasedPoolAllocator::~HeapBasedPoolAllocator
~HeapBasedPoolAllocator()
Definition: heap_based_pool_allocator.hpp:85
uavcan::HeapBasedPoolAllocator::num_allocated_blocks_
uint16_t num_allocated_blocks_
Definition: heap_based_pool_allocator.hpp:56
uavcan::uint8_t
std::uint8_t uint8_t
Definition: std.hpp:24
uavcan::NumericTraits
struct UAVCAN_EXPORT NumericTraits
Definition: templates.hpp:342
uavcan::HeapBasedPoolAllocator::allocate
virtual void * allocate(std::size_t size)
Definition: heap_based_pool_allocator.hpp:100
uavcan::HeapBasedPoolAllocator::deallocate
virtual void deallocate(const void *ptr)
Definition: heap_based_pool_allocator.hpp:143
uavcan::max
const UAVCAN_EXPORT T & max(const T &a, const T &b)
Definition: templates.hpp:291
uavcan::IPoolAllocator
Definition: dynamic_memory.hpp:21
uavcan::HeapBasedPoolAllocator::capacity_soft_limit_
const uint16_t capacity_soft_limit_
Definition: heap_based_pool_allocator.hpp:52
UAVCAN_EXPORT
#define UAVCAN_EXPORT
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:108
uavcan::min
const UAVCAN_EXPORT T & min(const T &a, const T &b)
Definition: templates.hpp:281
build_config.hpp
uavcan::HeapBasedPoolAllocator::getBlockCapacity
virtual uint16_t getBlockCapacity() const
Definition: heap_based_pool_allocator.hpp:161
uavcan::HeapBasedPoolAllocator::getBlockCapacityHardLimit
uint16_t getBlockCapacityHardLimit() const
Definition: heap_based_pool_allocator.hpp:166
uavcan::HeapBasedPoolAllocator::shrink
void shrink()
Definition: heap_based_pool_allocator.hpp:172
RaiiSynchronizer
Definition: heap_based_pool_allocator.cpp:116
uavcan::HeapBasedPoolAllocator::HeapBasedPoolAllocator
HeapBasedPoolAllocator(uint16_t block_capacity_soft_limit, uint16_t block_capacity_hard_limit=0)
Definition: heap_based_pool_allocator.hpp:70
uavcan::HeapBasedPoolAllocator::num_reserved_blocks_
uint16_t num_reserved_blocks_
Definition: heap_based_pool_allocator.hpp:55
uavcan::HeapBasedPoolAllocator::getNumAllocatedBlocks
uint16_t getNumAllocatedBlocks() const
Definition: heap_based_pool_allocator.hpp:200
pyuavcan_v0.introspect.node
node
Definition: introspect.py:398
uavcan::HeapBasedPoolAllocator
Definition: heap_based_pool_allocator.hpp:40
uavcan
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:204
uavcan::HeapBasedPoolAllocator::Node::next
Node * next
Definition: heap_based_pool_allocator.hpp:45
uavcan::Node
Definition: node.hpp:38
UAVCAN_LIKELY
#define UAVCAN_LIKELY(x)
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:192


uavcan_communicator
Author(s):
autogenerated on Fri Dec 13 2024 03:10:02