From 86deb6e868dac2865dc091cf2674ab9f4aee54eb Mon Sep 17 00:00:00 2001 From: Nick Banks Date: Fri, 14 Oct 2016 09:02:38 -0700 Subject: [PATCH] Platform Support for Dynamic Memory Allocation (#767) * Add support for platform implementation of dynamic memory allocation. --- .../libopenthread.vcxproj.filters | 12 +++ etc/visual-studio/libopenthread_k.vcxproj | 1 - .../libopenthread_k.vcxproj.filters | 15 ++- etc/visual-studio/mbedtls_k.vcxproj | 8 +- include/platform/Makefile.am | 1 + include/platform/memory.h | 91 +++++++++++++++++++ include/platform/toolchain.h | 17 ++++ src/core/common/new.hpp | 3 + src/core/meshcop/dtls.cpp | 8 ++ src/core/meshcop/dtls.hpp | 6 ++ src/core/openthread-instance.h | 2 + src/core/openthread.cpp | 7 +- third_party/mbedtls/mbedtls-config.h | 9 +- 13 files changed, 167 insertions(+), 13 deletions(-) create mode 100644 include/platform/memory.h diff --git a/etc/visual-studio/libopenthread.vcxproj.filters b/etc/visual-studio/libopenthread.vcxproj.filters index fe2cf0c07..2ab491035 100644 --- a/etc/visual-studio/libopenthread.vcxproj.filters +++ b/etc/visual-studio/libopenthread.vcxproj.filters @@ -216,6 +216,12 @@ Source Files\utils + + Source Files\meshcop + + + Source Files\thread + @@ -407,5 +413,11 @@ Header Files\utils + + Header Files\meshcop + + + Header Files\thread + \ No newline at end of file diff --git a/etc/visual-studio/libopenthread_k.vcxproj b/etc/visual-studio/libopenthread_k.vcxproj index defeda33d..e3381bc38 100644 --- a/etc/visual-studio/libopenthread_k.vcxproj +++ b/etc/visual-studio/libopenthread_k.vcxproj @@ -30,7 +30,6 @@ - diff --git a/etc/visual-studio/libopenthread_k.vcxproj.filters b/etc/visual-studio/libopenthread_k.vcxproj.filters index fe7bb636b..3776cd43a 100644 --- a/etc/visual-studio/libopenthread_k.vcxproj.filters +++ b/etc/visual-studio/libopenthread_k.vcxproj.filters @@ -207,15 +207,18 @@ Source Files\crypto - - Source Files\crypto - Source Files\crypto Source Files\utils + + Source Files\thread + + + Source Files\meshcop + @@ -407,5 +410,11 @@ Header Files\utils + + Header Files\thread + + + Header Files\meshcop + \ No newline at end of file diff --git a/etc/visual-studio/mbedtls_k.vcxproj b/etc/visual-studio/mbedtls_k.vcxproj index 1a9934901..a8ee990e9 100644 --- a/etc/visual-studio/mbedtls_k.vcxproj +++ b/etc/visual-studio/mbedtls_k.vcxproj @@ -106,7 +106,7 @@ ..\..\include;..\..\src\missing\stdint;..\..\src\missing\stdbool;..\..\src\core;..\..\third_party\mbedtls;..\..\third_party\mbedtls\repo\include;..\..\third_party\mbedtls\repo\include\mbedtls - WIN32;MBEDTLS_CONFIG_FILE="mbedtls-config.h";WINDOWS_KERNEL;%(PreprocessorDefinitions) + WIN32;MBEDTLS_CONFIG_FILE="mbedtls-config.h";WINDOWS_KERNEL;OPENTHREAD_MULTIPLE_INSTANCE;%(PreprocessorDefinitions) 4132;4242;4245;4748;%(DisableSpecificWarnings) Level4 true @@ -115,7 +115,7 @@ ..\..\include;..\..\src\missing\stdint;..\..\src\missing\stdbool;..\..\src\core;..\..\third_party\mbedtls;..\..\third_party\mbedtls\repo\include;..\..\third_party\mbedtls\repo\include\mbedtls - _WIN64;_AMD64_;AMD64;MBEDTLS_CONFIG_FILE="mbedtls-config.h";WINDOWS_KERNEL;%(PreprocessorDefinitions) + _WIN64;_AMD64_;AMD64;MBEDTLS_CONFIG_FILE="mbedtls-config.h";WINDOWS_KERNEL;OPENTHREAD_MULTIPLE_INSTANCE;%(PreprocessorDefinitions) 4132;4242;4245;4748;%(DisableSpecificWarnings) Level4 true @@ -124,7 +124,7 @@ ..\..\include;..\..\src\missing\stdint;..\..\src\missing\stdbool;..\..\src\core;..\..\third_party\mbedtls;..\..\third_party\mbedtls\repo\include;..\..\third_party\mbedtls\repo\include\mbedtls - WIN32;MBEDTLS_CONFIG_FILE="mbedtls-config.h";WINDOWS_KERNEL;%(PreprocessorDefinitions) + WIN32;MBEDTLS_CONFIG_FILE="mbedtls-config.h";WINDOWS_KERNEL;OPENTHREAD_MULTIPLE_INSTANCE;%(PreprocessorDefinitions) 4132;4242;4245;4603;4627;4986;4987;4996;%(DisableSpecificWarnings) Level4 true @@ -133,7 +133,7 @@ ..\..\include;..\..\src\missing\stdint;..\..\src\missing\stdbool;..\..\src\core;..\..\third_party\mbedtls;..\..\third_party\mbedtls\repo\include;..\..\third_party\mbedtls\repo\include\mbedtls - _WIN64;_AMD64_;AMD64;MBEDTLS_CONFIG_FILE="mbedtls-config.h";WINDOWS_KERNEL;%(PreprocessorDefinitions) + _WIN64;_AMD64_;AMD64;MBEDTLS_CONFIG_FILE="mbedtls-config.h";WINDOWS_KERNEL;OPENTHREAD_MULTIPLE_INSTANCE;%(PreprocessorDefinitions) 4132;4242;4245;4603;4627;4986;4987;4996;%(DisableSpecificWarnings) Level4 true diff --git a/include/platform/Makefile.am b/include/platform/Makefile.am index f829ea0d5..3928f1ca3 100644 --- a/include/platform/Makefile.am +++ b/include/platform/Makefile.am @@ -31,6 +31,7 @@ include $(abs_top_nlbuild_autotools_dir)/automake/pre.am ot_platform_headers =\ alarm.h \ diag.h \ + memory.h \ misc.h \ logging.h \ platform.h \ diff --git a/include/platform/memory.h b/include/platform/memory.h new file mode 100644 index 000000000..e1b9db0c2 --- /dev/null +++ b/include/platform/memory.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2016, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * @brief + * This file includes the platform abstraction for dynamic memory allocation. + */ + +#ifndef MEMORY_H_ +#define MEMORY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup memory Memory + * @ingroup platform + * + * @brief + * This module includes the platform abstraction for dynamic memory allocation. + * + * @{ + * + */ + +// Currently, OpenThread only requires dynamic memory allocation when supporting multiple +// simultaneous instances, for MbedTls. +#ifdef OPENTHREAD_MULTIPLE_INSTANCE + +/** + * Dynamically allocates new memory. On platforms that support it, should just redirect to calloc. For + * those that don't support calloc, should support the same functionality: + * + * "The calloc() function contiguously allocates enough space for count objects that are size bytes of + * memory each and returns a pointer to the allocated memory. The allocated memory is filled with bytes + * of value zero." + * + * @param[in] aNum The number of blocks to allocate + * @param[in] aSize The size of each block to allocate + * + * @retval void* The pointer to the front of the memory allocated + * @retval NULL Failed to allocate the memory requested. + */ +void *otPlatCAlloc(size_t aNum, size_t aSize); + +/** + * Frees memory that was dynamically allocated. + * + * @param[in] aPtr A pointer the memory blocks to free. The pointer may be NULL. + */ +void otPlatFree(void *aPtr); + +#endif + +/** + * @} + * + */ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // DEBUG_H_ diff --git a/include/platform/toolchain.h b/include/platform/toolchain.h index ca854409a..9b9d39d8d 100644 --- a/include/platform/toolchain.h +++ b/include/platform/toolchain.h @@ -134,6 +134,23 @@ extern "C" { // =========== TOOLCHAIN SELECTION : END =========== +#ifdef _MSC_VER + +#ifdef _WIN64 +#define OT_CALL +#define OT_CDECL +#else +#define OT_CALL __stdcall +#define OT_CDECL __cdecl +#endif + +#else + +#define OT_CALL +#define OT_CDECL + +#endif + /** * @} * diff --git a/src/core/common/new.hpp b/src/core/common/new.hpp index 591b7d47f..209d2880b 100644 --- a/src/core/common/new.hpp +++ b/src/core/common/new.hpp @@ -35,7 +35,10 @@ #define NEW_HPP_ #include +#include inline void *operator new(size_t, void *p) throw() { return p; } +void OT_CDECL operator delete(void *, size_t) throw(); + #endif // NEW_HPP_ diff --git a/src/core/meshcop/dtls.cpp b/src/core/meshcop/dtls.cpp index 49222c895..58856d9c3 100644 --- a/src/core/meshcop/dtls.cpp +++ b/src/core/meshcop/dtls.cpp @@ -59,6 +59,14 @@ Dtls::Dtls(ThreadNetif &aNetif): mProvisioningUrl.Init(); } +Dtls::~Dtls(void) +{ + if (mStarted) + { + Close(); + } +} + ThreadError Dtls::Start(bool aClient, ReceiveHandler aReceiveHandler, SendHandler aSendHandler, void *aContext) { static const int ciphersuites[2] = {0xC0FF, 0}; // EC-JPAKE cipher suite diff --git a/src/core/meshcop/dtls.hpp b/src/core/meshcop/dtls.hpp index 67497122f..b3b2167a3 100644 --- a/src/core/meshcop/dtls.hpp +++ b/src/core/meshcop/dtls.hpp @@ -69,6 +69,12 @@ public: */ Dtls(ThreadNetif &aNetif); + /** + * This destructor cleans up the DTLS object. + * + */ + ~Dtls(void); + /** * This function pointer is called when data is received from the DTLS session. * diff --git a/src/core/openthread-instance.h b/src/core/openthread-instance.h index 5dd0124bf..96a460926 100644 --- a/src/core/openthread-instance.h +++ b/src/core/openthread-instance.h @@ -71,7 +71,9 @@ typedef struct otInstance // State // +#ifndef OPENTHREAD_MULTIPLE_INSTANCE Thread::Crypto::MbedTls mMbedTls; +#endif Thread::Ip6::Ip6 mIp6; Thread::ThreadNetif mThreadNetif; diff --git a/src/core/openthread.cpp b/src/core/openthread.cpp index f70627c01..340ef32af 100644 --- a/src/core/openthread.cpp +++ b/src/core/openthread.cpp @@ -63,6 +63,8 @@ static otDEFINE_ALIGNED_VAR(sInstanceRaw, sizeof(otInstance), uint64_t); otInstance *sInstance = NULL; #endif +void OT_CDECL operator delete(void *, size_t) throw() { } + otInstance::otInstance(void) : mReceiveIp6DatagramCallback(NULL), mReceiveIp6DatagramCallbackContext(NULL), @@ -70,8 +72,6 @@ otInstance::otInstance(void) : mActiveScanCallbackContext(NULL), mDiscoverCallback(NULL), mDiscoverCallbackContext(NULL), - mMbedTls(), - mIp6(), mThreadNetif(mIp6) { } @@ -1051,7 +1051,8 @@ void otInstanceFinalize(otInstance *aInstance) (void)otThreadStop(aInstance); (void)otInterfaceDown(aInstance); - // Nothing to actually free, since the caller supplied the buffer + // Free the otInstance structure + delete aInstance; #ifndef OPENTHREAD_MULTIPLE_INSTANCE sInstance = NULL; diff --git a/third_party/mbedtls/mbedtls-config.h b/third_party/mbedtls/mbedtls-config.h index 64cced6b5..39a73104a 100644 --- a/third_party/mbedtls/mbedtls-config.h +++ b/third_party/mbedtls/mbedtls-config.h @@ -31,6 +31,7 @@ #include #include +#include #if defined(_WIN32) #include @@ -1905,7 +1906,9 @@ * * Enable this module to enable the buffer memory allocator. */ +#ifndef OPENTHREAD_MULTIPLE_INSTANCE #define MBEDTLS_MEMORY_BUFFER_ALLOC_C +#endif /** * \def MBEDTLS_NET_C @@ -2475,8 +2478,10 @@ /* Platform options */ //#define MBEDTLS_PLATFORM_STD_MEM_HDR /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ -//#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */ +#ifdef OPENTHREAD_MULTIPLE_INSTANCE +#define MBEDTLS_PLATFORM_STD_CALLOC otPlatCAlloc /**< Default allocator to use, can be undefined */ +#define MBEDTLS_PLATFORM_STD_FREE otPlatFree /**< Default free to use, can be undefined */ +#endif //#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ //#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined */ //#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */