0.01.00
heap.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017, The OpenThread Authors.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. Neither the name of the copyright holder nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
35 #ifndef OT_HEAP_HPP_
36 #define OT_HEAP_HPP_
37 
38 #include "openthread-core-config.h"
39 
40 #include <stddef.h>
41 
42 #include "utils/wrap_stdint.h"
43 
44 namespace ot {
45 namespace Crypto {
46 
47 
63 class Block
64 {
65  friend class Heap;
66 
67 public:
74  uint16_t GetSize(void) const {
75  return mSize;
76  }
77 
84  void SetSize(uint16_t aSize) {
85  mSize = aSize;
86  }
87 
98  uint16_t GetNext(void) const {
99  return *reinterpret_cast<const uint16_t *>(reinterpret_cast<const uint8_t *>(this) + sizeof(mSize) + mSize);
100  }
101 
110  void SetNext(uint16_t aNext) {
111  *reinterpret_cast<uint16_t *>(reinterpret_cast<uint8_t *>(this) + sizeof(mSize) + mSize) = aNext;
112  }
113 
120  void *GetPointer(void) {
121  return &mMemory;
122  }
123 
130  uint16_t GetLeftNext(void) const {
131  return *(&mSize - 1);
132  }
133 
141  bool IsLeftFree(void) const {
142  return GetLeftNext() != 0;
143  }
144 
152  bool IsFree(void) const {
153  return mSize != kGuardBlockSize && GetNext() != 0;
154  }
155 
156 private:
157  enum
158  {
159  kGuardBlockSize = 0xffff,
160  };
161 
162  uint16_t mSize;
163 
169  uint8_t mMemory[sizeof(uint16_t)];
170 };
171 
186 class Heap
187 {
188 public:
193  Heap(void);
194 
206  void *CAlloc(size_t aCount, size_t aSize);
207 
214  void Free(void *aPointer);
215 
220  bool IsClean(void) {
221  const Block &super = BlockSuper();
222  const Block &first = BlockRight(super);
223  return super.GetNext() == BlockOffset(first) && first.GetSize() == kFirstBlockSize;
224  }
225 
230  size_t GetCapacity(void) const {
231  return kFirstBlockSize;
232  }
233 
234 private:
235  enum
236  {
237 #if OPENTHREAD_ENABLE_DTLS
239 #else
241 #endif
242  kAlignSize = sizeof(long),
243  kBlockRemainderSize = kAlignSize - sizeof(uint16_t) * 2,
244  kSuperBlockSize = kAlignSize - sizeof(Block),
245  kFirstBlockSize = kMemorySize - kAlignSize * 3 +
246  kBlockRemainderSize,
247  kSuperBlockOffset = kAlignSize - sizeof(uint16_t),
248  kFirstBlockOffset = kAlignSize * 2 - sizeof(uint16_t),
249  kGuardBlockOffset = kMemorySize - sizeof(uint16_t),
250  };
251 
260  Block &BlockAt(uint16_t aOffset) {
261  return *reinterpret_cast<Block *>(&mMemory.m16[aOffset / 2]);
262  }
263 
272  Block &BlockOf(void *aPointer) {
273  uint16_t offset = static_cast<uint16_t>(reinterpret_cast<uint8_t *>(aPointer) - mMemory.m8);
274  offset -= sizeof(uint16_t);
275  return BlockAt(offset);
276  }
277 
284  Block &BlockSuper(void) {
285  return BlockAt(kSuperBlockOffset);
286  }
287 
296  Block &BlockNext(const Block &aBlock) {
297  return BlockAt(aBlock.GetNext());
298  }
299 
308  Block &BlockRight(const Block &aBlock) {
309  return BlockAt(BlockOffset(aBlock) + sizeof(Block) + aBlock.GetSize());
310  }
311 
318  Block &BlockPrev(const Block &aBlock);
319 
326  bool IsLeftFree(const Block &aBlock) {
327  return (BlockOffset(aBlock) != kFirstBlockOffset && aBlock.IsLeftFree());
328  }
329 
338  uint16_t BlockOffset(const Block &aBlock) {
339  return static_cast<uint16_t>(reinterpret_cast<const uint8_t *>(&aBlock) - mMemory.m8);
340  }
341 
351  void BlockInsert(Block &aPrev, Block &aBlock);
352 
353  union
354  {
355  // Make sure memory is long aligned.
356  long mLong[kMemorySize / sizeof(long)];
357  uint8_t m8[kMemorySize];
358  uint16_t m16[kMemorySize / sizeof(uint16_t)];
359  } mMemory;
360 };
361 
362 } // namespace Crypto
363 } // namespace ot
364 
365 #endif // OT_HEAP_HPP_
Definition: cli.cpp:90
This class defines functionality to manipulate heap.
Definition: heap.hpp:186
void SetNext(uint16_t aNext)
This method updates the offset of the free block after this block.
Definition: heap.hpp:110
#define OPENTHREAD_CONFIG_MBEDTLS_HEAP_SIZE
The size of mbedTLS heap buffer when DTLS is enabled.
Definition: openthread-core-default-config.h:862
void * GetPointer(void)
This method returns the pointer to the start of the memory for user.
Definition: heap.hpp:120
uint16_t GetLeftNext(void) const
This method returns the offset of the free block after the left neighbor block.
Definition: heap.hpp:130
uint16_t GetNext(void) const
This method returns the offset of the free block after this block.
Definition: heap.hpp:98
uint16_t GetSize(void) const
This method returns the size of this block.
Definition: heap.hpp:74
bool IsClean(void)
This method returns whether the heap is clean.
Definition: heap.hpp:220
bool IsLeftFree(void) const
This method returns whether the left neighbor block is a free block.
Definition: heap.hpp:141
#define OPENTHREAD_CONFIG_MBEDTLS_HEAP_SIZE_NO_DTLS
The size of mbedTLS heap buffer when DTLS is disabled.
Definition: openthread-core-default-config.h:872
This class represents a memory block.
Definition: heap.hpp:63
void SetSize(uint16_t aSize)
This method updates the size of this block.
Definition: heap.hpp:84
bool IsFree(void) const
This method returns whether the current block is a free block.
Definition: heap.hpp:152
This file includes compile-time configuration constants for OpenThread.
size_t GetCapacity(void) const
This method returns the capacity of this heap.
Definition: heap.hpp:230