dynamic_memory.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
3  */
4 
5 #ifndef UAVCAN_DYNAMIC_MEMORY_HPP_INCLUDED
6 #define UAVCAN_DYNAMIC_MEMORY_HPP_INCLUDED
7 
8 #include <cassert>
9 #include <cstdlib>
10 #include <cstring>
11 #include <uavcan/std.hpp>
14 #include <uavcan/build_config.hpp>
15 
16 namespace uavcan
17 {
22 {
23 public:
24  virtual ~IPoolAllocator() { }
25 
26  virtual void* allocate(std::size_t size) = 0;
27  virtual void deallocate(const void* ptr) = 0;
28 
32  virtual uint16_t getBlockCapacity() const = 0;
33 };
34 
48 template <std::size_t PoolSize,
49  uint8_t BlockSize,
50  typename RaiiSynchronizer = char>
53 {
54  union Node
55  {
56  uint8_t data[BlockSize];
58  };
59 
61  union
62  {
63  uint8_t bytes[PoolSize];
64  long double _aligner1;
65  long long _aligner2;
67  } pool_;
68 
71 
72 public:
73  static const uint16_t NumBlocks = PoolSize / BlockSize;
74 
75  PoolAllocator();
76 
77  virtual void* allocate(std::size_t size);
78  virtual void deallocate(const void* ptr);
79 
80  virtual uint16_t getBlockCapacity() const { return NumBlocks; }
81 
86  {
87  RaiiSynchronizer lock;
88  (void)lock;
89  return used_;
90  }
92  {
93  RaiiSynchronizer lock;
94  (void)lock;
95  return static_cast<uint16_t>(NumBlocks - used_);
96  }
97 
102  {
103  RaiiSynchronizer lock;
104  (void)lock;
105  return max_used_;
106  }
107 };
108 
113 {
117 
118 public:
120  : allocator_(allocator)
121  , max_blocks_(static_cast<uint16_t>(min<std::size_t>(max_blocks, 0xFFFFU)))
122  , used_blocks_(0)
123  {
125  }
126 
127  virtual void* allocate(std::size_t size);
128  virtual void deallocate(const void* ptr);
129 
130  virtual uint16_t getBlockCapacity() const;
131 };
132 
133 // ----------------------------------------------------------------------------
134 
135 /*
136  * PoolAllocator<>
137  */
138 template <std::size_t PoolSize, uint8_t BlockSize, typename RaiiSynchronizer>
140 
141 template <std::size_t PoolSize, uint8_t BlockSize, typename RaiiSynchronizer>
143  free_list_(reinterpret_cast<Node*>(pool_.bytes)),
144  used_(0),
145  max_used_(0)
146 {
147  // The limit is imposed by the width of the pool usage tracking variables.
148  StaticAssert<((PoolSize / BlockSize) <= 0xFFFFU)>::check();
149 
150  (void)std::memset(pool_.bytes, 0, PoolSize);
151  for (unsigned i = 0; (i + 1) < (NumBlocks - 1 + 1); i++) // -Werror=type-limits
152  {
153  // coverity[dead_error_line : FALSE]
154  free_list_[i].next = free_list_ + i + 1;
155  }
156  free_list_[NumBlocks - 1].next = UAVCAN_NULLPTR;
157 }
158 
159 template <std::size_t PoolSize, uint8_t BlockSize, typename RaiiSynchronizer>
161 {
162  if (free_list_ == UAVCAN_NULLPTR || size > BlockSize)
163  {
164  return UAVCAN_NULLPTR;
165  }
166 
167  RaiiSynchronizer lock;
168  (void)lock;
169 
170  void* pmem = free_list_;
171  free_list_ = free_list_->next;
172 
173  // Statistics
174  UAVCAN_ASSERT(used_ < NumBlocks);
175  used_++;
176  if (used_ > max_used_)
177  {
178  max_used_ = used_;
179  }
180 
181  return pmem;
182 }
183 
184 template <std::size_t PoolSize, uint8_t BlockSize, typename RaiiSynchronizer>
186 {
187  if (ptr == UAVCAN_NULLPTR)
188  {
189  return;
190  }
191 
192  RaiiSynchronizer lock;
193  (void)lock;
194 
195  Node* p = static_cast<Node*>(const_cast<void*>(ptr));
196  p->next = free_list_;
197  free_list_ = p;
198 
199  // Statistics
200  UAVCAN_ASSERT(used_ > 0);
201  used_--;
202 }
203 
204 }
205 
206 #endif // UAVCAN_DYNAMIC_MEMORY_HPP_INCLUDED
UAVCAN_NULLPTR
#define UAVCAN_NULLPTR
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:51
uavcan::Noncopyable
Definition: templates.hpp:46
templates.hpp
std::size_t
unsigned long size_t
Definition: coverity_scan_model.cpp:19
uavcan::PoolAllocator::Node
Definition: dynamic_memory.hpp:54
uavcan::PoolAllocator::PoolAllocator
PoolAllocator()
Definition: dynamic_memory.hpp:142
uavcan::PoolAllocator::_aligner3
Node _aligner3
Definition: dynamic_memory.hpp:66
uavcan::IPoolAllocator::~IPoolAllocator
virtual ~IPoolAllocator()
Definition: dynamic_memory.hpp:24
uavcan::LimitedPoolAllocator
Definition: dynamic_memory.hpp:112
uavcan::LimitedPoolAllocator::allocator_
IPoolAllocator & allocator_
Definition: dynamic_memory.hpp:114
uavcan::PoolAllocator::NumBlocks
static const uint16_t NumBlocks
Definition: dynamic_memory.hpp:73
uavcan::StaticAssert
struct UAVCAN_EXPORT StaticAssert
Definition: templates.hpp:29
std.hpp
placement_new.hpp
uavcan::PoolAllocator
Definition: dynamic_memory.hpp:51
uavcan::uint16_t
std::uint16_t uint16_t
Definition: std.hpp:25
uavcan::PoolAllocator::_aligner1
long double _aligner1
Definition: dynamic_memory.hpp:64
uavcan::LimitedPoolAllocator::max_blocks_
const uint16_t max_blocks_
Definition: dynamic_memory.hpp:115
uavcan::PoolAllocator::getNumFreeBlocks
uint16_t getNumFreeBlocks() const
Definition: dynamic_memory.hpp:91
uavcan::LimitedPoolAllocator::allocate
virtual void * allocate(std::size_t size)
Definition: uc_dynamic_memory.cpp:12
uavcan::uint8_t
std::uint8_t uint8_t
Definition: std.hpp:24
uavcan::LimitedPoolAllocator::LimitedPoolAllocator
LimitedPoolAllocator(IPoolAllocator &allocator, std::size_t max_blocks)
Definition: dynamic_memory.hpp:119
uavcan::IPoolAllocator
Definition: dynamic_memory.hpp:21
uavcan::LimitedPoolAllocator::getBlockCapacity
virtual uint16_t getBlockCapacity() const
Definition: uc_dynamic_memory.cpp:36
UAVCAN_EXPORT
#define UAVCAN_EXPORT
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:108
uavcan::PoolAllocator::getPeakNumUsedBlocks
uint16_t getPeakNumUsedBlocks() const
Definition: dynamic_memory.hpp:101
uavcan::min
const UAVCAN_EXPORT T & min(const T &a, const T &b)
Definition: templates.hpp:281
uavcan::PoolAllocator::max_used_
uint16_t max_used_
Definition: dynamic_memory.hpp:70
build_config.hpp
uavcan::PoolAllocator::Node::next
Node * next
Definition: dynamic_memory.hpp:57
uavcan::PoolAllocator::_aligner2
long long _aligner2
Definition: dynamic_memory.hpp:65
uavcan::PoolAllocator::used_
uint16_t used_
Definition: dynamic_memory.hpp:69
RaiiSynchronizer
Definition: heap_based_pool_allocator.cpp:116
uavcan::PoolAllocator::getNumUsedBlocks
uint16_t getNumUsedBlocks() const
Definition: dynamic_memory.hpp:85
std
uavcan::LimitedPoolAllocator::deallocate
virtual void deallocate(const void *ptr)
Definition: uc_dynamic_memory.cpp:25
uavcan
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:204
uavcan::LimitedPoolAllocator::used_blocks_
uint16_t used_blocks_
Definition: dynamic_memory.hpp:116
uavcan::PoolAllocator::getBlockCapacity
virtual uint16_t getBlockCapacity() const
Definition: dynamic_memory.hpp:80
uavcan::Node
Definition: node.hpp:38
UAVCAN_ASSERT
#define UAVCAN_ASSERT(x)
Definition: libuavcan/libuavcan/include/uavcan/build_config.hpp:184
uavcan::PoolAllocator::free_list_
Node * free_list_
Definition: dynamic_memory.hpp:60


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