mirror of
https://github.com/espressif/openthread.git
synced 2026-08-24 03:09:52 +00:00
[utils] make heap for general use (#2667)
* move heap into utils namespace * add api to get free space of heap
This commit is contained in:
@@ -135,7 +135,6 @@ SOURCES_COMMON = \
|
||||
common/trickle_timer.cpp \
|
||||
crypto/aes_ccm.cpp \
|
||||
crypto/aes_ecb.cpp \
|
||||
crypto/heap.cpp \
|
||||
crypto/hmac_sha256.cpp \
|
||||
crypto/mbedtls.cpp \
|
||||
crypto/pbkdf2_cmac.cpp \
|
||||
@@ -196,6 +195,7 @@ SOURCES_COMMON = \
|
||||
utils/channel_manager.cpp \
|
||||
utils/channel_monitor.cpp \
|
||||
utils/child_supervision.cpp \
|
||||
utils/heap.cpp \
|
||||
utils/jam_detector.cpp \
|
||||
utils/missing_strlcpy.c \
|
||||
utils/missing_strlcat.c \
|
||||
@@ -252,7 +252,6 @@ HEADERS_COMMON = \
|
||||
common/trickle_timer.hpp \
|
||||
crypto/aes_ccm.hpp \
|
||||
crypto/aes_ecb.hpp \
|
||||
crypto/heap.hpp \
|
||||
crypto/hmac_sha256.hpp \
|
||||
crypto/mbedtls.hpp \
|
||||
crypto/pbkdf2_cmac.h \
|
||||
@@ -324,6 +323,7 @@ HEADERS_COMMON = \
|
||||
utils/channel_monitor.hpp \
|
||||
utils/child_supervision.hpp \
|
||||
utils/slaac_address.hpp \
|
||||
utils/heap.hpp \
|
||||
utils/jam_detector.hpp \
|
||||
utils/wrap_stdbool.h \
|
||||
utils/wrap_stdint.h \
|
||||
|
||||
@@ -50,8 +50,8 @@
|
||||
#include "coap/coap.hpp"
|
||||
#include "common/code_utils.hpp"
|
||||
#if !OPENTHREAD_ENABLE_MULTIPLE_INSTANCES
|
||||
#include "crypto/heap.hpp"
|
||||
#include "crypto/mbedtls.hpp"
|
||||
#include "utils/heap.hpp"
|
||||
#endif
|
||||
#include "common/notifier.hpp"
|
||||
#include "common/settings.hpp"
|
||||
@@ -275,12 +275,12 @@ public:
|
||||
|
||||
#if !OPENTHREAD_ENABLE_MULTIPLE_INSTANCES
|
||||
/**
|
||||
* This method returns a reference to the MbedTlsHeap object.
|
||||
* This method returns a reference to the Heap object.
|
||||
*
|
||||
* @returns A reference to the MbedTlsHeap object.
|
||||
* @returns A reference to the Heap object.
|
||||
*
|
||||
*/
|
||||
Crypto::Heap &GetMbedTlsHeap(void) { return mMbedTlsHeap; }
|
||||
Utils::Heap &GetHeap(void) { return mHeap; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -386,7 +386,7 @@ private:
|
||||
|
||||
#if !OPENTHREAD_ENABLE_MULTIPLE_INSTANCES
|
||||
Crypto::MbedTls mMbedTls;
|
||||
Crypto::Heap mMbedTlsHeap;
|
||||
Utils::Heap mHeap;
|
||||
#endif
|
||||
|
||||
Ip6::Ip6 mIp6;
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
|
||||
#include <mbedtls/platform.h>
|
||||
|
||||
#include "heap.hpp"
|
||||
#include "common/instance.hpp"
|
||||
|
||||
#if !OPENTHREAD_ENABLE_MULTIPLE_INSTANCES
|
||||
@@ -45,12 +44,12 @@ namespace Crypto {
|
||||
|
||||
static void *CAlloc(size_t aCount, size_t aSize)
|
||||
{
|
||||
return Instance::Get().GetMbedTlsHeap().CAlloc(aCount, aSize);
|
||||
return Instance::Get().GetHeap().CAlloc(aCount, aSize);
|
||||
}
|
||||
|
||||
static void Free(void *aPointer)
|
||||
{
|
||||
Instance::Get().GetMbedTlsHeap().Free(aPointer);
|
||||
Instance::Get().GetHeap().Free(aPointer);
|
||||
}
|
||||
|
||||
MbedTls::MbedTls(void)
|
||||
|
||||
@@ -989,23 +989,23 @@
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_MBEDTLS_HEAP_SIZE
|
||||
* @def OPENTHREAD_CONFIG_HEAP_SIZE
|
||||
*
|
||||
* The size of mbedTLS heap buffer when DTLS is enabled.
|
||||
* The size of heap buffer when DTLS is enabled.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_MBEDTLS_HEAP_SIZE
|
||||
#define OPENTHREAD_CONFIG_MBEDTLS_HEAP_SIZE (1536 * sizeof(void *))
|
||||
#ifndef OPENTHREAD_CONFIG_HEAP_SIZE
|
||||
#define OPENTHREAD_CONFIG_HEAP_SIZE (1536 * sizeof(void *))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def OPENTHREAD_CONFIG_MBEDTLS_HEAP_SIZE_NO_DTLS
|
||||
* @def OPENTHREAD_CONFIG_HEAP_SIZE_NO_DTLS
|
||||
*
|
||||
* The size of mbedTLS heap buffer when DTLS is disabled.
|
||||
* The size of heap buffer when DTLS is disabled.
|
||||
*
|
||||
*/
|
||||
#ifndef OPENTHREAD_CONFIG_MBEDTLS_HEAP_SIZE_NO_DTLS
|
||||
#define OPENTHREAD_CONFIG_MBEDTLS_HEAP_SIZE_NO_DTLS 384
|
||||
#ifndef OPENTHREAD_CONFIG_HEAP_SIZE_NO_DTLS
|
||||
#define OPENTHREAD_CONFIG_HEAP_SIZE_NO_DTLS 384
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#include "common/code_utils.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Crypto {
|
||||
namespace Utils {
|
||||
|
||||
Heap::Heap(void)
|
||||
{
|
||||
@@ -55,6 +55,8 @@ Heap::Heap(void)
|
||||
|
||||
super.SetNext(BlockOffset(first));
|
||||
first.SetNext(BlockOffset(guard));
|
||||
|
||||
mMemory.mFreeSize = kFirstBlockSize;
|
||||
}
|
||||
|
||||
void *Heap::CAlloc(size_t aCount, size_t aSize)
|
||||
@@ -100,8 +102,12 @@ void *Heap::CAlloc(size_t aCount, size_t aSize)
|
||||
{
|
||||
BlockInsert(BlockSuper(), newBlock);
|
||||
}
|
||||
|
||||
mMemory.mFreeSize -= sizeof(Block);
|
||||
}
|
||||
|
||||
mMemory.mFreeSize -= curr->GetSize();
|
||||
|
||||
curr->SetNext(0);
|
||||
|
||||
memset(curr->GetPointer(), 0, size);
|
||||
@@ -146,11 +152,15 @@ void Heap::Free(void *aPointer)
|
||||
Block &block = BlockOf(aPointer);
|
||||
Block &right = BlockRight(block);
|
||||
|
||||
mMemory.mFreeSize += block.GetSize();
|
||||
|
||||
if (IsLeftFree(block))
|
||||
{
|
||||
Block *prev = &BlockSuper();
|
||||
Block *left = &BlockNext(*prev);
|
||||
|
||||
mMemory.mFreeSize += sizeof(Block);
|
||||
|
||||
for (const uint16_t offset = block.GetLeftNext(); left->GetNext() != offset; left = &BlockNext(*left))
|
||||
{
|
||||
prev = left;
|
||||
@@ -162,6 +172,8 @@ void Heap::Free(void *aPointer)
|
||||
|
||||
if (right.IsFree())
|
||||
{
|
||||
mMemory.mFreeSize += sizeof(Block);
|
||||
|
||||
if (right.GetSize() > left->GetSize())
|
||||
{
|
||||
for (const uint16_t offset = BlockOffset(right); prev->GetNext() != offset; prev = &BlockNext(*prev))
|
||||
@@ -193,6 +205,8 @@ void Heap::Free(void *aPointer)
|
||||
prev.SetNext(right.GetNext());
|
||||
block.SetSize(block.GetSize() + right.GetSize() + sizeof(Block));
|
||||
BlockInsert(prev, block);
|
||||
|
||||
mMemory.mFreeSize += sizeof(Block);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -201,5 +215,5 @@ void Heap::Free(void *aPointer)
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Crypto
|
||||
} // namespace Utils
|
||||
} // namespace ot
|
||||
@@ -42,7 +42,7 @@
|
||||
#include "utils/wrap_stdint.h"
|
||||
|
||||
namespace ot {
|
||||
namespace Crypto {
|
||||
namespace Utils {
|
||||
|
||||
/**
|
||||
* This class represents a memory block.
|
||||
@@ -206,11 +206,12 @@ public:
|
||||
* This method returns whether the heap is clean.
|
||||
*
|
||||
*/
|
||||
bool IsClean(void)
|
||||
bool IsClean(void) const
|
||||
{
|
||||
const Block &super = BlockSuper();
|
||||
const Block &first = BlockRight(super);
|
||||
return super.GetNext() == BlockOffset(first) && first.GetSize() == kFirstBlockSize;
|
||||
Heap & self = *const_cast<Heap *>(this);
|
||||
const Block &super = self.BlockSuper();
|
||||
const Block &first = self.BlockRight(super);
|
||||
return super.GetNext() == self.BlockOffset(first) && first.GetSize() == kFirstBlockSize;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -219,13 +220,18 @@ public:
|
||||
*/
|
||||
size_t GetCapacity(void) const { return kFirstBlockSize; }
|
||||
|
||||
/**
|
||||
* This method returns free space of this heap.
|
||||
*/
|
||||
size_t GetFreeSize(void) const { return mMemory.mFreeSize; }
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
#if OPENTHREAD_ENABLE_DTLS
|
||||
kMemorySize = OPENTHREAD_CONFIG_MBEDTLS_HEAP_SIZE, ///< Size of memory buffer (bytes).
|
||||
kMemorySize = OPENTHREAD_CONFIG_HEAP_SIZE, ///< Size of memory buffer (bytes).
|
||||
#else
|
||||
kMemorySize = OPENTHREAD_CONFIG_MBEDTLS_HEAP_SIZE_NO_DTLS, ///< Size of memory buffer (bytes).
|
||||
kMemorySize = OPENTHREAD_CONFIG_HEAP_SIZE_NO_DTLS, ///< Size of memory buffer (bytes).
|
||||
#endif
|
||||
kAlignSize = sizeof(long), ///< The alignment size.
|
||||
kBlockRemainderSize = kAlignSize - sizeof(uint16_t) * 2, ///< Block unit remainder size.
|
||||
@@ -331,6 +337,7 @@ private:
|
||||
|
||||
union
|
||||
{
|
||||
uint16_t mFreeSize;
|
||||
// Make sure memory is long aligned.
|
||||
long mLong[kMemorySize / sizeof(long)];
|
||||
uint8_t m8[kMemorySize];
|
||||
@@ -338,7 +345,7 @@ private:
|
||||
} mMemory;
|
||||
};
|
||||
|
||||
} // namespace Crypto
|
||||
} // namespace Utils
|
||||
} // namespace ot
|
||||
|
||||
#endif // OT_HEAP_HPP_
|
||||
@@ -163,8 +163,8 @@ test_link_quality_SOURCES = test_platform.cpp test_link_quality.cpp
|
||||
test_lowpan_LDADD = $(COMMON_LDADD)
|
||||
test_lowpan_SOURCES = test_platform.cpp test_lowpan.cpp test_util.cpp
|
||||
|
||||
test_network_data_LDADD = $(COMMON_LDADD)
|
||||
test_network_data_SOURCES = test_platform.cpp test_network_data.cpp
|
||||
test_network_data_LDADD = $(COMMON_LDADD)
|
||||
test_network_data_SOURCES = test_platform.cpp test_network_data.cpp
|
||||
|
||||
test_mac_frame_LDADD = $(COMMON_LDADD)
|
||||
test_mac_frame_SOURCES = test_platform.cpp test_mac_frame.cpp
|
||||
|
||||
+15
-11
@@ -28,7 +28,7 @@
|
||||
|
||||
#include <openthread/config.h>
|
||||
|
||||
#include "core/crypto/heap.hpp"
|
||||
#include "core/utils/heap.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -45,15 +45,17 @@
|
||||
*/
|
||||
void TestAllocateSingle(void)
|
||||
{
|
||||
ot::Crypto::Heap heap;
|
||||
ot::Utils::Heap heap;
|
||||
|
||||
const size_t totalSize = heap.GetFreeSize();
|
||||
|
||||
{
|
||||
void *p = heap.CAlloc(1, 0);
|
||||
VerifyOrQuit(p == NULL, "TestAllocateSingle allocate 1 x 0 byte failed!\n");
|
||||
VerifyOrQuit(p == NULL && totalSize == heap.GetFreeSize(), "TestAllocateSingle allocate 1 x 0 byte failed!\n");
|
||||
heap.Free(p);
|
||||
|
||||
p = heap.CAlloc(0, 1);
|
||||
VerifyOrQuit(p == NULL, "TestAllocateSingle allocate 0 x 1 byte failed!\n");
|
||||
VerifyOrQuit(p == NULL && totalSize == heap.GetFreeSize(), "TestAllocateSingle allocate 0 x 1 byte failed!\n");
|
||||
heap.Free(p);
|
||||
}
|
||||
|
||||
@@ -61,10 +63,10 @@ void TestAllocateSingle(void)
|
||||
{
|
||||
Log("%s allocating %zu bytes...", __func__, size);
|
||||
void *p = heap.CAlloc(1, size);
|
||||
VerifyOrQuit(p != NULL && !heap.IsClean(), "allocating failed!\n");
|
||||
VerifyOrQuit(p != NULL && !heap.IsClean() && heap.GetFreeSize() + size <= totalSize, "allocating failed!\n");
|
||||
memset(p, 0xff, size);
|
||||
heap.Free(p);
|
||||
VerifyOrQuit(heap.IsClean(), "freeing failed!\n");
|
||||
VerifyOrQuit(heap.IsClean() && heap.GetFreeSize() == totalSize, "freeing failed!\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,13 +85,14 @@ void TestAllocateRandomly(size_t aSizeLimit, unsigned int aSeed)
|
||||
size_t mSize;
|
||||
};
|
||||
|
||||
ot::Crypto::Heap heap;
|
||||
Node head;
|
||||
size_t nnodes = 0;
|
||||
ot::Utils::Heap heap;
|
||||
Node head;
|
||||
size_t nnodes = 0;
|
||||
|
||||
srand(aSeed);
|
||||
|
||||
Node *last = &head;
|
||||
const size_t totalSize = heap.GetFreeSize();
|
||||
Node * last = &head;
|
||||
|
||||
do
|
||||
{
|
||||
@@ -146,7 +149,8 @@ void TestAllocateRandomly(size_t aSizeLimit, unsigned int aSeed)
|
||||
last = next;
|
||||
}
|
||||
|
||||
VerifyOrQuit(heap.IsClean(), "TestAllocateRandomly heap not clean after freeing all!\n");
|
||||
VerifyOrQuit(heap.IsClean() && heap.GetFreeSize() == totalSize,
|
||||
"TestAllocateRandomly heap not clean after freeing all!\n");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user