diff --git a/src/inet/InetLayer.cpp b/src/inet/InetLayer.cpp index ddd856d7394d2f..c1f570fc206545 100644 --- a/src/inet/InetLayer.cpp +++ b/src/inet/InetLayer.cpp @@ -281,14 +281,26 @@ INET_ERROR InetLayer::Init(chip::System::Layer & aSystemLayer, void * aContext) State = kState_Initialized; -#if CHIP_SYSTEM_CONFIG_USE_SOCKETS -#if INET_CONFIG_ENABLE_DNS_RESOLVER && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS +#if INET_CONFIG_ENABLE_RAW_ENDPOINT + RawEndPoint::sPool.Init(); +#endif + +#if INET_CONFIG_ENABLE_UDP_ENDPOINT + UDPEndPoint::sPool.Init(); +#endif + +#if INET_CONFIG_ENABLE_TCP_ENDPOINT + TCPEndPoint::sPool.Init(); +#endif + +#if INET_CONFIG_ENABLE_DNS_RESOLVER + DNSResolver::sPool.Init(); +#if CHIP_SYSTEM_CONFIG_USE_SOCKETS && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS err = mAsyncDNSResolver.Init(this); SuccessOrExit(err); - -#endif // INET_CONFIG_ENABLE_DNS_RESOLVER && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS -#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS +#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS +#endif // INET_CONFIG_ENABLE_DNS_RESOLVER exit: Platform::InetLayer::DidInit(this, mContext, err); @@ -331,10 +343,10 @@ INET_ERROR InetLayer::Shutdown() } #if CHIP_SYSTEM_CONFIG_USE_SOCKETS && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS - err = mAsyncDNSResolver.Shutdown(); - #endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS && INET_CONFIG_ENABLE_ASYNC_DNS_SOCKETS + + DNSResolver::sPool.Shutdown(); #endif // INET_CONFIG_ENABLE_DNS_RESOLVER #if INET_CONFIG_ENABLE_RAW_ENDPOINT @@ -347,6 +359,8 @@ INET_ERROR InetLayer::Shutdown() lEndPoint->Close(); } } + + RawEndPoint::sPool.Shutdown(); #endif // INET_CONFIG_ENABLE_RAW_ENDPOINT #if INET_CONFIG_ENABLE_TCP_ENDPOINT @@ -359,6 +373,8 @@ INET_ERROR InetLayer::Shutdown() lEndPoint->Abort(); } } + + TCPEndPoint::sPool.Shutdown(); #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT #if INET_CONFIG_ENABLE_UDP_ENDPOINT @@ -371,6 +387,8 @@ INET_ERROR InetLayer::Shutdown() lEndPoint->Close(); } } + + UDPEndPoint::sPool.Shutdown(); #endif // INET_CONFIG_ENABLE_UDP_ENDPOINT } diff --git a/src/platform/Linux/SystemPlatformConfig.h b/src/platform/Linux/SystemPlatformConfig.h index 8c8520f018533d..278bd3988adf2c 100644 --- a/src/platform/Linux/SystemPlatformConfig.h +++ b/src/platform/Linux/SystemPlatformConfig.h @@ -39,8 +39,8 @@ struct ChipDeviceEvent; #define CHIP_SYSTEM_CONFIG_NO_LOCKING 0 #define CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_EVENT_FUNCTIONS 1 #define CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME 0 - #define CHIP_SYSTEM_CONFIG_USE_POSIX_TIME_FUNCTS 1 +#define CHIP_SYSTEM_CONFIG_POOL_USE_HEAP 1 // ========== Platform-specific Configuration Overrides ========= diff --git a/src/system/SystemConfig.h b/src/system/SystemConfig.h index 16347e5f6d3a35..465d6467034dd5 100644 --- a/src/system/SystemConfig.h +++ b/src/system/SystemConfig.h @@ -202,6 +202,16 @@ #define CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING 0 #endif /* CHIP_SYSTEM_CONFIG_FREERTOS_LOCKING */ +/** + * @def CHIP_SYSTEM_CONFIG_POOL_USE_HEAP + * + * @brief + * Allocate Pool from Heap for large systems (e.g. Linux). + */ +#ifndef CHIP_SYSTEM_CONFIG_POOL_USE_HEAP +#define CHIP_SYSTEM_CONFIG_POOL_USE_HEAP 0 +#endif /* CHIP_SYSTEM_CONFIG_POOL_USE_HEAP */ + /** * @def CHIP_SYSTEM_CONFIG_NO_LOCKING * diff --git a/src/system/SystemLayer.cpp b/src/system/SystemLayer.cpp index 203aa4693b31a9..7c7b4472293904 100644 --- a/src/system/SystemLayer.cpp +++ b/src/system/SystemLayer.cpp @@ -129,6 +129,8 @@ Error Layer::Init(void * aContext) { Error lReturn; + Timer::sPool.Init(); + RegisterLayerErrorFormatter(); #if CHIP_SYSTEM_CONFIG_USE_SOCKETS RegisterPOSIXErrorFormatter(); @@ -198,6 +200,7 @@ Error Layer::Shutdown() this->mContext = nullptr; this->mLayerState = kLayerState_NotInitialized; + Timer::sPool.Shutdown(); exit: Platform::Layer::DidShutdown(*this, lContext, lReturn); return lReturn; diff --git a/src/system/SystemObject.cpp b/src/system/SystemObject.cpp index c909f94b3dc997..87ffaea6c920cb 100644 --- a/src/system/SystemObject.cpp +++ b/src/system/SystemObject.cpp @@ -35,7 +35,6 @@ // Include local headers #include #include -#include namespace chip { namespace System { diff --git a/src/system/SystemObject.h b/src/system/SystemObject.h index 4b74cdd7eb8d49..e2252b0d85dd00 100644 --- a/src/system/SystemObject.h +++ b/src/system/SystemObject.h @@ -34,8 +34,10 @@ // Include dependent headers #include #include +#include #include +#include #include #include @@ -160,7 +162,11 @@ inline Object::~Object() {} template union ObjectArena { +#if CHIP_SYSTEM_CONFIG_POOL_USE_HEAP + uint8_t * uMemory; +#else uint8_t uMemory[SIZE]; +#endif ALIGN uAlign; }; @@ -175,6 +181,9 @@ template class ObjectPool { public: + void Init(); + void Reset(); + void Shutdown(); static size_t Size(); T * Get(const Layer & aLayer, size_t aIndex); @@ -185,6 +194,9 @@ class ObjectPool friend class TestObject; ObjectArena mArena; +#if CHIP_SYSTEM_CONFIG_POOL_USE_HEAP + unsigned int mRefCount = 0; +#endif #if CHIP_SYSTEM_CONFIG_PROVIDE_STATISTICS void GetNumObjectsInUse(unsigned int aStartIndex, unsigned int & aNumInUse); @@ -193,6 +205,59 @@ class ObjectPool #endif }; +template +inline void ObjectPool::Init() +{ +#if CHIP_SYSTEM_CONFIG_POOL_USE_HEAP + unsigned int oldCount = __sync_fetch_and_add(&this->mRefCount, 1); + + if (oldCount == 0) + { + mArena.uMemory = reinterpret_cast(chip::Platform::MemoryAlloc(N * sizeof(T))); + memset(mArena.uMemory, 0, N * sizeof(T)); +#if CHIP_SYSTEM_CONFIG_PROVIDE_STATISTICS + mHighWatermark = 0; +#endif + } +#endif +} + +template +inline void ObjectPool::Shutdown() +{ +#if CHIP_SYSTEM_CONFIG_POOL_USE_HEAP + unsigned int oldCount = __sync_fetch_and_sub(&this->mRefCount, 1); + + if (oldCount == 1) + { + if (mArena.uMemory) + { + chip::Platform::MemoryFree(mArena.uMemory); + mArena.uMemory = nullptr; + } + + __sync_synchronize(); + } + else if (oldCount == 0) + { + abort(); + } +#endif + +#if CHIP_SYSTEM_CONFIG_PROVIDE_STATISTICS + mHighWatermark = 0; +#endif +} + +template +inline void ObjectPool::Reset() +{ + memset(mArena.uMemory, 0, N * sizeof(T)); +#if CHIP_SYSTEM_CONFIG_PROVIDE_STATISTICS + mHighWatermark = 0; +#endif +} + /** * @brief * Returns the number of objects that can be simultaneously retained from a pool. diff --git a/src/system/tests/TestSystemObject.cpp b/src/system/tests/TestSystemObject.cpp index 29079f2881525a..9dbca81b4bf68d 100644 --- a/src/system/tests/TestSystemObject.cpp +++ b/src/system/tests/TestSystemObject.cpp @@ -70,6 +70,13 @@ static int Finalize(void * aContext); class TestObject : public Object { public: + enum + { + kPoolSize = 122 // a multiple of kNumThreads, less than CHIP_SYS_STATS_COUNT_MAX + }; + + static ObjectPool sPool; + Error Init(); static void CheckRetention(nlTestSuite * inSuite, void * aContext); @@ -78,12 +85,6 @@ class TestObject : public Object static void CheckHighWatermarkConcurrency(nlTestSuite * inSuite, void * aContext); private: - enum - { - kPoolSize = 122 // a multiple of kNumThreads, less than CHIP_SYS_STATS_COUNT_MAX - }; - static ObjectPool sPool; - #if CHIP_SYSTEM_CONFIG_POSIX_LOCKING unsigned int mDelay; @@ -137,7 +138,7 @@ void TestObject::CheckRetention(nlTestSuite * inSuite, void * aContext) unsigned int i, j; lLayer.Init(lContext.mLayerContext); - memset(&sPool, 0, sizeof(sPool)); + sPool.Reset(); for (i = 0; i < kPoolSize; ++i) { @@ -332,7 +333,7 @@ void TestObject::MultithreadedTest(nlTestSuite * inSuite, void * aContext, void TestContext & lContext = *static_cast(aContext); pthread_t lThread[kNumThreads]; - memset(&sPool, 0, sizeof(sPool)); + sPool.Reset(); for (unsigned int i = 0; i < kNumThreads; ++i) { @@ -369,7 +370,7 @@ void TestObject::CheckHighWatermarkConcurrency(nlTestSuite * inSuite, void * aCo void TestObject::CheckHighWatermark(nlTestSuite * inSuite, void * aContext) { - memset(&sPool, 0, sizeof(sPool)); + sPool.Reset(); const int kNumObjects = kPoolSize; TestObject * lObject = nullptr; @@ -488,6 +489,11 @@ static int Initialize(void * aContext) TestContext & lContext = *reinterpret_cast(aContext); void * lLayerContext = nullptr; + if (chip::Platform::MemoryInit() != CHIP_NO_ERROR) + return FAILURE; + + TestObject::sPool.Init(); + #if CHIP_SYSTEM_CONFIG_USE_LWIP && LWIP_VERSION_MAJOR <= 2 && LWIP_VERSION_MINOR < 1 static sys_mbox_t * sLwIPEventQueue = NULL; @@ -515,6 +521,9 @@ static int Finalize(void * aContext) lContext.mTestSuite = nullptr; + TestObject::sPool.Shutdown(); + chip::Platform::MemoryShutdown(); + return SUCCESS; }