diff --git a/.github/workflows/simulation.yml b/.github/workflows/simulation.yml index 674afed25..831a9181e 100644 --- a/.github/workflows/simulation.yml +++ b/.github/workflows/simulation.yml @@ -194,6 +194,9 @@ jobs: cli-mtd: runs-on: ubuntu-18.04 + strategy: + matrix: + message_use_heap: [0, 1] env: CFLAGS: -m32 CXXFLAGS: -m32 @@ -202,6 +205,7 @@ jobs: REFERENCE_DEVICE: 1 USE_MTD: 1 VIRTUAL_TIME: 1 + MESSAGE_USE_HEAP: ${{ matrix.message_use_heap }} steps: - uses: actions/checkout@v2 - name: Bootstrap diff --git a/etc/cmake/options.cmake b/etc/cmake/options.cmake index ce0c180fe..ea3479006 100644 --- a/etc/cmake/options.cmake +++ b/etc/cmake/options.cmake @@ -146,6 +146,11 @@ if(OT_DUA) target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_DUA_ENABLE=1") endif() +option(OT_MESSAGE_USE_HEAP "enable heap allocator for message buffers") +if(OT_MESSAGE_USE_HEAP) + target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE=1") +endif() + option(OT_MLR "enable Multicast Listener Registration feature for Thread 1.2") if(OT_MLR) target_compile_definitions(ot-config INTERFACE "OPENTHREAD_CONFIG_MLR_ENABLE=1") diff --git a/etc/gn/openthread.gni b/etc/gn/openthread.gni index 68ede5dc8..e69261201 100644 --- a/etc/gn/openthread.gni +++ b/etc/gn/openthread.gni @@ -162,6 +162,9 @@ if (openthread_enable_core_config_args) { # Enable mac filter support openthread_config_mac_filter_enable = false + # Enable use built-in heap for message buffers + openthread_config_message_use_heap = false + # Enable MLE long routes extension (experimental, breaks Thread conformance] openthread_config_mle_long_routes_enable = false diff --git a/examples/common-switches.mk b/examples/common-switches.mk index 0649a61e0..a9630c18d 100644 --- a/examples/common-switches.mk +++ b/examples/common-switches.mk @@ -61,6 +61,7 @@ LOG_OUTPUT ?= APP endif LINK_RAW ?= 0 MAC_FILTER ?= 0 +MESSAGE_USE_HEAP ?= 0 MLE_LONG_ROUTES ?= 0 MLR ?= 0 MTD_NETDIAG ?= 0 @@ -214,6 +215,10 @@ ifeq ($(MAC_FILTER),1) COMMONCFLAGS += -DOPENTHREAD_CONFIG_MAC_FILTER_ENABLE=1 endif +ifeq ($(MESSAGE_USE_HEAP),1) +COMMONCFLAGS += -DOPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE=1 +endif + # Enable MLE long routes extension (experimental, breaks Thread conformance) ifeq ($(MLE_LONG_ROUTES),1) COMMONCFLAGS += -DOPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE=1 diff --git a/script/check-size b/script/check-size index 4387e5432..bd1a554a9 100755 --- a/script/check-size +++ b/script/check-size @@ -120,6 +120,7 @@ size_nrf52840_version() "JOINER=1" "LINK_RAW=1" "MAC_FILTER=1" + "MESSAGE_USE_HEAP=1" "MTD_NETDIAG=1" "SERVICE=1" "SLAAC=1" diff --git a/script/test b/script/test index 7de8fe87e..80b328cd0 100755 --- a/script/test +++ b/script/test @@ -48,7 +48,7 @@ readonly VERBOSE="${VERBOSE:-0}" build_simulation() { local version="$1" - local options=("-DOT_THREAD_VERSION=${version}" "-DBUILD_TESTING=ON" "-DOT_REFERENCE_DEVICE=ON") + local options=("-DOT_MESSAGE_USE_HEAP=ON" "-DOT_THREAD_VERSION=${version}" "-DBUILD_TESTING=ON" "-DOT_REFERENCE_DEVICE=ON") if [[ ${version} == "1.2" ]]; then options+=("-DOT_DUA=ON") @@ -87,7 +87,7 @@ build_simulation() build_posix() { local version="$1" - local options=("-DOT_THREAD_VERSION=${version}" "-DBUILD_TESTING=ON") + local options=("-DOT_MESSAGE_USE_HEAP=ON" "-DOT_THREAD_VERSION=${version}" "-DBUILD_TESTING=ON") if [[ ${version} == "1.2" ]]; then options+=("-DOT_DUA=ON") diff --git a/src/core/BUILD.gn b/src/core/BUILD.gn index d6e565d44..859a19935 100644 --- a/src/core/BUILD.gn +++ b/src/core/BUILD.gn @@ -176,6 +176,10 @@ if (openthread_enable_core_config_args) { defines += [ "OPENTHREAD_CONFIG_MAC_FILTER_ENABLE=1" ] } + if (openthread_config_message_use_heap) { + defines += [ "OPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE=1" ] + } + if (openthread_config_mle_long_routes_enable) { defines += [ "OPENTHREAD_CONFIG_MLE_LONG_ROUTES_ENABLE=1" ] } diff --git a/src/core/common/message.cpp b/src/core/common/message.cpp index 54e582604..1f1bfe9cb 100644 --- a/src/core/common/message.cpp +++ b/src/core/common/message.cpp @@ -41,11 +41,12 @@ #include "net/checksum.hpp" #include "net/ip6.hpp" +#if OPENTHREAD_MTD || OPENTHREAD_FTD namespace ot { MessagePool::MessagePool(Instance &aInstance) : InstanceLocator(aInstance) -#if !OPENTHREAD_CONFIG_PLATFORM_MESSAGE_MANAGEMENT +#if !OPENTHREAD_CONFIG_PLATFORM_MESSAGE_MANAGEMENT && !OPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE , mNumFreeBuffers(kNumBuffers) #endif { @@ -103,21 +104,24 @@ Buffer *MessagePool::NewBuffer(Message::Priority aPriority) { Buffer *buffer = nullptr; - SuccessOrExit(ReclaimBuffers(1, aPriority)); - -#if OPENTHREAD_CONFIG_PLATFORM_MESSAGE_MANAGEMENT - - buffer = static_cast(otPlatMessagePoolNew(&GetInstance())); - + while (( +#if OPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE + buffer = static_cast(GetInstance().HeapCAlloc(sizeof(Buffer), 1)) +#elif OPENTHREAD_CONFIG_PLATFORM_MESSAGE_MANAGEMENT + buffer = static_cast(otPlatMessagePoolNew(&GetInstance())) #else - - buffer = mBufferPool.Allocate(); - VerifyOrExit(buffer != nullptr); - - mNumFreeBuffers--; - buffer->SetNextBuffer(nullptr); - + buffer = mBufferPool.Allocate() #endif + ) == nullptr) + { + SuccessOrExit(ReclaimBuffers(aPriority)); + } + +#if !OPENTHREAD_CONFIG_PLATFORM_MESSAGE_MANAGEMENT && !OPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE + mNumFreeBuffers--; +#endif + + buffer->SetNextBuffer(nullptr); exit: if (buffer == nullptr) @@ -133,7 +137,9 @@ void MessagePool::FreeBuffers(Buffer *aBuffer) while (aBuffer != nullptr) { Buffer *next = aBuffer->GetNextBuffer(); -#if OPENTHREAD_CONFIG_PLATFORM_MESSAGE_MANAGEMENT +#if OPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE + GetInstance().HeapFree(aBuffer); +#elif OPENTHREAD_CONFIG_PLATFORM_MESSAGE_MANAGEMENT otPlatMessagePoolFree(&GetInstance(), aBuffer); #else mBufferPool.Free(*aBuffer); @@ -143,30 +149,18 @@ void MessagePool::FreeBuffers(Buffer *aBuffer) } } -otError MessagePool::ReclaimBuffers(int aNumBuffers, Message::Priority aPriority) +otError MessagePool::ReclaimBuffers(Message::Priority aPriority) { -#if OPENTHREAD_MTD || OPENTHREAD_FTD - while (aNumBuffers > GetFreeBufferCount()) - { - SuccessOrExit(Get().EvictMessage(aPriority)); - } - -exit: -#else - OT_UNUSED_VARIABLE(aPriority); -#endif - - // First comparison is to get around issues with comparing - // signed and unsigned numbers, if aNumBuffers is negative then - // the second comparison wont be attempted. - return (aNumBuffers < 0 || aNumBuffers <= GetFreeBufferCount()) ? OT_ERROR_NONE : OT_ERROR_NO_BUFS; + return Get().EvictMessage(aPriority); } uint16_t MessagePool::GetFreeBufferCount(void) const { uint16_t rval; -#if OPENTHREAD_CONFIG_PLATFORM_MESSAGE_MANAGEMENT +#if OPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE + rval = static_cast(GetInstance().GetHeap().GetFreeSize() / sizeof(Buffer)); +#elif OPENTHREAD_CONFIG_PLATFORM_MESSAGE_MANAGEMENT rval = otPlatMessagePoolNumFreeBuffers(&GetInstance()); #else rval = mNumFreeBuffers; @@ -254,23 +248,9 @@ otError Message::SetLength(uint16_t aLength) { otError error = OT_ERROR_NONE; uint16_t totalLengthRequest = GetReserved() + aLength; - uint16_t totalLengthCurrent = GetReserved() + GetLength(); - int bufs = 0; VerifyOrExit(totalLengthRequest >= GetReserved(), error = OT_ERROR_INVALID_ARGS); - if (totalLengthRequest > kHeadBufferDataSize) - { - bufs = (((totalLengthRequest - kHeadBufferDataSize) - 1) / kBufferDataSize) + 1; - } - - if (totalLengthCurrent > kHeadBufferDataSize) - { - bufs -= (((totalLengthCurrent - kHeadBufferDataSize) - 1) / kBufferDataSize) + 1; - } - - SuccessOrExit(error = GetMessagePool()->ReclaimBuffers(bufs, GetPriority())); - SuccessOrExit(error = ResizeMessage(totalLengthRequest)); GetMetadata().mLength = aLength; @@ -871,3 +851,4 @@ void PriorityQueue::GetInfo(uint16_t &aMessageCount, uint16_t &aBufferCount) con } } // namespace ot +#endif // OPENTHREAD_MTD || OPENTHREAD_FTD diff --git a/src/core/common/message.hpp b/src/core/common/message.hpp index 10b602a68..e98072dae 100644 --- a/src/core/common/message.hpp +++ b/src/core/common/message.hpp @@ -1471,9 +1471,9 @@ public: private: Buffer *NewBuffer(Message::Priority aPriority); void FreeBuffers(Buffer *aBuffer); - otError ReclaimBuffers(int aNumBuffers, Message::Priority aPriority); + otError ReclaimBuffers(Message::Priority aPriority); -#if OPENTHREAD_CONFIG_PLATFORM_MESSAGE_MANAGEMENT == 0 +#if !OPENTHREAD_CONFIG_PLATFORM_MESSAGE_MANAGEMENT && !OPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE uint16_t mNumFreeBuffers; Pool mBufferPool; #endif diff --git a/src/core/config/openthread-core-config-check.h b/src/core/config/openthread-core-config-check.h index c3cf4f5ac..aefd661df 100644 --- a/src/core/config/openthread-core-config-check.h +++ b/src/core/config/openthread-core-config-check.h @@ -546,4 +546,13 @@ "(and OPENTHREAD_CONFIG_LOG_DEFINE_AS_MACRO_ONLY)" #endif +#if OPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE +#if !OPENTHREAD_CONFIG_DTLS_ENABLE +#error "OPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE is strongly discouraged when OPENTHREAD_CONFIG_DTLS_ENABLE is off." +#endif +#if OPENTHREAD_CONFIG_PLATFORM_MESSAGE_MANAGEMENT +#error "OPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE conflicts with OPENTHREAD_CONFIG_PLATFORM_MESSAGE_MANAGEMENT." +#endif +#endif + #endif // OPENTHREAD_CORE_CONFIG_CHECK_H_ diff --git a/src/core/config/openthread-core-default-config.h b/src/core/config/openthread-core-default-config.h index d67c500fb..d8b1a2e42 100644 --- a/src/core/config/openthread-core-default-config.h +++ b/src/core/config/openthread-core-default-config.h @@ -127,6 +127,18 @@ #define OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE 0 #endif +/** + * @def OPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE + * + * Whether use heap allocator for message buffers. + * + * @note If this is set, OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS is ignored. + * + */ +#ifndef OPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE +#define OPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE 0 +#endif + /** * @def OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS * diff --git a/tests/toranj/openthread-core-toranj-config.h b/tests/toranj/openthread-core-toranj-config.h index 5b8d0ef31..df9d8dfca 100644 --- a/tests/toranj/openthread-core-toranj-config.h +++ b/tests/toranj/openthread-core-toranj-config.h @@ -119,6 +119,14 @@ */ #define OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS 256 +/** + * @def OPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE + * + * Whether use heap allocator for message buffers. + * + */ +#define OPENTHREAD_CONFIG_MESSAGE_USE_HEAP_ENABLE 1 + /** * @def OPENTHREAD_CONFIG_TMF_ADDRESS_CACHE_ENTRIES *