[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:
Yakun Xu
2018-04-18 09:48:13 -07:00
committed by Jonathan Hui
parent f849ce37c6
commit 88b6822ac1
8 changed files with 65 additions and 41 deletions
+2 -2
View File
@@ -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 \
+5 -5
View File
@@ -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;
+2 -3
View File
@@ -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)
+8 -8
View File
@@ -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_
+2 -2
View File
@@ -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
View File
@@ -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");
}
/**