diff --git a/src/lib/dnssd/minimal_mdns/Server.h b/src/lib/dnssd/minimal_mdns/Server.h index f3fe1ef0c8bf4b..9c77dbec5fdd94 100644 --- a/src/lib/dnssd/minimal_mdns/Server.h +++ b/src/lib/dnssd/minimal_mdns/Server.h @@ -228,7 +228,8 @@ class ServerBase // The PoolImpl impl is used as a base class because its destructor must be called after ServerBase's destructor. template -class Server : private chip::PoolImpl, +class Server : private chip::PoolImpl, public ServerBase { public: diff --git a/src/lib/dnssd/minimal_mdns/tests/CheckOnlyServer.h b/src/lib/dnssd/minimal_mdns/tests/CheckOnlyServer.h index 6af8a16227fa4f..94e934cc22d185 100644 --- a/src/lib/dnssd/minimal_mdns/tests/CheckOnlyServer.h +++ b/src/lib/dnssd/minimal_mdns/tests/CheckOnlyServer.h @@ -71,7 +71,8 @@ void MakePrintableName(char (&location)[N], FullQName name) } // namespace -class CheckOnlyServer : private chip::PoolImpl, +class CheckOnlyServer : private chip::PoolImpl, public ServerBase, public ParserDelegate, public TxtRecordDelegate diff --git a/src/lib/support/Pool.h b/src/lib/support/Pool.h index 4a36fa28202856..a2ccd53aed2f60 100644 --- a/src/lib/support/Pool.h +++ b/src/lib/support/Pool.h @@ -336,33 +336,28 @@ class HeapObjectPool : public internal::Statistics, public internal::PoolCommon< #endif // CHIP_SYSTEM_CONFIG_POOL_USE_HEAP -#if CHIP_SYSTEM_CONFIG_POOL_USE_HEAP -template -using ObjectPool = HeapObjectPool; -#else // CHIP_SYSTEM_CONFIG_POOL_USE_HEAP -template -using ObjectPool = BitMapObjectPool; -#endif // CHIP_SYSTEM_CONFIG_POOL_USE_HEAP - enum class ObjectPoolMem { kStatic, #if CHIP_SYSTEM_CONFIG_POOL_USE_HEAP - kDynamic + kDynamic, + kDefault = kDynamic +#else // CHIP_SYSTEM_CONFIG_POOL_USE_HEAP + kDefault = kStatic #endif // CHIP_SYSTEM_CONFIG_POOL_USE_HEAP }; -template -class MemTypeObjectPool; +template +class ObjectPool; template -class MemTypeObjectPool : public BitMapObjectPool +class ObjectPool : public BitMapObjectPool { }; #if CHIP_SYSTEM_CONFIG_POOL_USE_HEAP template -class MemTypeObjectPool : public HeapObjectPool +class ObjectPool : public HeapObjectPool { }; #endif // CHIP_SYSTEM_CONFIG_POOL_USE_HEAP diff --git a/src/lib/support/PoolWrapper.h b/src/lib/support/PoolWrapper.h index 13195ca70310df..ca338b4d7c6e89 100644 --- a/src/lib/support/PoolWrapper.h +++ b/src/lib/support/PoolWrapper.h @@ -53,11 +53,11 @@ class PoolInterface virtual Loop ForEachActiveObjectInner(void * context, Lambda lambda) = 0; }; -template +template class PoolProxy; -template -class PoolProxy> : public PoolInterface +template +class PoolProxy> : public PoolInterface { public: static_assert(std::is_base_of::value, "Interface type is not derived from Pool type"); @@ -83,7 +83,7 @@ class PoolProxy> : public PoolInter return Impl().ForEachActiveObject([&](T * target) { return lambda(context, static_cast(target)); }); } - virtual BitMapObjectPool & Impl() = 0; + virtual ObjectPool & Impl() = 0; }; /* @@ -92,23 +92,24 @@ class PoolProxy> : public PoolInter * * @tparam T a subclass of element to be allocated. * @tparam N a positive integer max number of elements the pool provides. + * @tparam M an ObjectPoolMem constant selecting static vs heap allocation. * @tparam Interfaces a list of parameters which defines PoolInterface's. each interface is defined by a * std::tuple. The PoolImpl is derived from every * PoolInterface, the PoolImpl can be converted to the interface type * and passed around */ -template -class PoolImpl : public PoolProxy... +template +class PoolImpl : public PoolProxy... { public: PoolImpl() {} virtual ~PoolImpl() override {} protected: - virtual BitMapObjectPool & Impl() override { return mImpl; } + virtual ObjectPool & Impl() override { return mImpl; } private: - BitMapObjectPool mImpl; + ObjectPool mImpl; }; } // namespace chip diff --git a/src/lib/support/tests/TestPool.cpp b/src/lib/support/tests/TestPool.cpp index b78e684abf8866..2d26e260e581db 100644 --- a/src/lib/support/tests/TestPool.cpp +++ b/src/lib/support/tests/TestPool.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -53,7 +54,7 @@ using namespace chip; template void TestReleaseNull(nlTestSuite * inSuite, void * inContext) { - MemTypeObjectPool pool; + ObjectPool pool; pool.ReleaseObject(nullptr); NL_TEST_ASSERT(inSuite, GetNumObjectsInUse(pool) == 0); NL_TEST_ASSERT(inSuite, pool.Allocated() == 0); @@ -74,7 +75,7 @@ void TestReleaseNullDynamic(nlTestSuite * inSuite, void * inContext) template void TestCreateReleaseObject(nlTestSuite * inSuite, void * inContext) { - MemTypeObjectPool pool; + ObjectPool pool; uint32_t * obj[N]; NL_TEST_ASSERT(inSuite, pool.Allocated() == 0); @@ -105,7 +106,7 @@ void TestCreateReleaseObjectStatic(nlTestSuite * inSuite, void * inContext) constexpr const size_t kSize = 100; TestCreateReleaseObject(inSuite, inContext); - MemTypeObjectPool pool; + ObjectPool pool; uint32_t * obj[kSize]; for (size_t i = 0; i < kSize; ++i) @@ -159,7 +160,7 @@ void TestCreateReleaseStruct(nlTestSuite * inSuite, void * inContext) std::set objs1; constexpr const size_t kSize = 100; - MemTypeObjectPool pool; + ObjectPool pool; S * objs2[kSize]; for (size_t i = 0; i < kSize; ++i) @@ -223,7 +224,7 @@ void TestForEachActiveObject(nlTestSuite * inSuite, void * inContext) S * objArray[kSize]; std::set objIds; - MemTypeObjectPool pool; + ObjectPool pool; for (size_t i = 0; i < kSize; ++i) { @@ -343,6 +344,69 @@ void TestForEachActiveObjectDynamic(nlTestSuite * inSuite, void * inContext) } #endif // CHIP_SYSTEM_CONFIG_POOL_USE_HEAP +template +void TestPoolInterface(nlTestSuite * inSuite, void * inContext) +{ + struct TestObject + { + TestObject(uint32_t * set, size_t id) : mSet(set), mId(id) { *mSet |= (1 << mId); } + ~TestObject() { *mSet &= ~(1 << mId); } + uint32_t * mSet; + size_t mId; + }; + using TestObjectPoolType = PoolInterface; + + struct PoolHolder + { + PoolHolder(TestObjectPoolType & testObjectPool) : mTestObjectPoolInterface(testObjectPool) {} + TestObjectPoolType & mTestObjectPoolInterface; + }; + + constexpr size_t kSize = 10; + PoolImpl testObjectPool; + PoolHolder poolHolder(testObjectPool); + uint32_t bits = 0; + + TestObject * objs2[kSize]; + for (size_t i = 0; i < kSize; ++i) + { + objs2[i] = poolHolder.mTestObjectPoolInterface.CreateObject(&bits, i); + NL_TEST_ASSERT(inSuite, objs2[i] != nullptr); + NL_TEST_ASSERT(inSuite, GetNumObjectsInUse(poolHolder.mTestObjectPoolInterface) == i + 1); + NL_TEST_ASSERT(inSuite, bits == (1ul << (i + 1)) - 1); + } + for (size_t i = 0; i < kSize; ++i) + { + poolHolder.mTestObjectPoolInterface.ReleaseObject(objs2[i]); + NL_TEST_ASSERT(inSuite, GetNumObjectsInUse(poolHolder.mTestObjectPoolInterface) == kSize - i - 1); + } + NL_TEST_ASSERT(inSuite, bits == 0); + + // Verify that ReleaseAll() calls the destructors. + for (size_t i = 0; i < kSize; ++i) + { + objs2[i] = poolHolder.mTestObjectPoolInterface.CreateObject(&bits, i); + } + NL_TEST_ASSERT(inSuite, bits == (1ul << kSize) - 1); + NL_TEST_ASSERT(inSuite, GetNumObjectsInUse(poolHolder.mTestObjectPoolInterface) == kSize); + + poolHolder.mTestObjectPoolInterface.ReleaseAll(); + NL_TEST_ASSERT(inSuite, bits == 0); + NL_TEST_ASSERT(inSuite, GetNumObjectsInUse(poolHolder.mTestObjectPoolInterface) == 0); +} + +void TestPoolInterfaceStatic(nlTestSuite * inSuite, void * inContext) +{ + TestPoolInterface(inSuite, inContext); +} + +#if CHIP_SYSTEM_CONFIG_POOL_USE_HEAP +void TestPoolInterfaceDynamic(nlTestSuite * inSuite, void * inContext) +{ + TestPoolInterface(inSuite, inContext); +} +#endif // CHIP_SYSTEM_CONFIG_POOL_USE_HEAP + int Setup(void * inContext) { return SUCCESS; @@ -365,11 +429,13 @@ static const nlTest sTests[] = { NL_TEST_DEF_FN(TestCreateReleaseObjectStatic), NL_TEST_DEF_FN(TestCreateReleaseStructStatic), NL_TEST_DEF_FN(TestForEachActiveObjectStatic), + NL_TEST_DEF_FN(TestPoolInterfaceStatic), #if CHIP_SYSTEM_CONFIG_POOL_USE_HEAP NL_TEST_DEF_FN(TestReleaseNullDynamic), NL_TEST_DEF_FN(TestCreateReleaseObjectDynamic), NL_TEST_DEF_FN(TestCreateReleaseStructDynamic), NL_TEST_DEF_FN(TestForEachActiveObjectDynamic), + NL_TEST_DEF_FN(TestPoolInterfaceDynamic), #endif // CHIP_SYSTEM_CONFIG_POOL_USE_HEAP NL_TEST_SENTINEL() // clang-format on diff --git a/src/transport/raw/TCP.h b/src/transport/raw/TCP.h index 44292b2e131592..3aed361eaa02d8 100644 --- a/src/transport/raw/TCP.h +++ b/src/transport/raw/TCP.h @@ -281,7 +281,7 @@ class TCP : public TCPBase private: friend class TCPTest; TCPBase::ActiveConnectionState mConnectionsBuffer[kActiveConnectionsSize]; - PoolImpl mPendingPackets; + PoolImpl mPendingPackets; }; } // namespace Transport