Skip to content

Commit

Permalink
Add heap allocation to lib/support/Pool.h
Browse files Browse the repository at this point in the history
#### Problem

We have too many pool allocators.

Previous PRs (project-chip#11428, project-chip#11487) transitionally use `BitMapObjectPool`
where previously `System::ObjectPool` had been used, but this lost
the ability to configure heap allocation.

#### Change overview

- Add a heap allocator (from project-chip#9590)
- Add allocation selection (from project-chip#11371)
- Use this for `System::Timer` (complementing project-chip#11487)

Co-authored-by: Zang MingJie <[email protected]>
Co-authored-by: C Freeman <[email protected]>

A future PR will use this for Inet pools (complementing project-chip#11428);
that is not done here because it would conflict with other Inet
changes under way.

#### Testing

CI; no changes to functionality.

CI should show `.bss` decreases corresponding to increases in project-chip#11487.
  • Loading branch information
kpschoedel committed Nov 11, 2021
1 parent d45cfaa commit 45c6b8b
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 2 deletions.
107 changes: 107 additions & 0 deletions src/lib/support/Pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,20 @@

#pragma once

#include <lib/support/CodeUtils.h>

#include <array>
#include <assert.h>
#include <atomic>
#include <limits>
#include <new>
#include <stddef.h>

#if CHIP_SYSTEM_CONFIG_POOL_USE_HEAP
#include <mutex>
#include <set>
#endif // CHIP_SYSTEM_CONFIG_POOL_USE_HEAP

namespace chip {

class StaticAllocatorBase
Expand Down Expand Up @@ -160,4 +167,104 @@ class BitMapObjectPool : public StaticAllocatorBitmap
} mData;
};

#if CHIP_SYSTEM_CONFIG_POOL_USE_HEAP

/**
* @brief
* A class template used for allocating Object subclass objects from an ObjectArena<> template union.
*
* @tparam T a class to be allocated from the arena.
*/
template <class T>
class HeapObjectPool
{
public:
template <typename... Args>
T * CreateObject(Args &&... args)
{
std::lock_guard<std::mutex> lock(mutex);
T * object = new T(std::forward<Args>(args)...);
if (object == nullptr)
{
return nullptr;
}

mObjects.insert(object);
return object;
}

void ReleaseObject(T * object)
{
std::lock_guard<std::mutex> lock(mutex);
auto iter = mObjects.find(object);
VerifyOrDie(iter != mObjects.end());
mObjects.erase(iter);
delete object;
}

template <typename... Args>
void ResetObject(T * element, Args &&... args)
{
element->~T();
new (element) T(std::forward<Args>(args)...);
}

/**
* @brief
* Run a functor for each active object in the pool
*
* @param function The functor of type `bool (*)(T*)`, return false to break the iteration
* @return bool Returns false if broke during iteration
*/
template <typename Function>
bool ForEachActiveObject(Function && function)
{
std::lock_guard<std::mutex> lock(mutex);
// Create a new copy of original set, allowing add/remove elements while iterating in the same thread.
for (auto object : std::set<T *>(mObjects))
{
if (!function(object))
return false;
}
return true;
}

private:
std::mutex mutex;
std::set<T *> mObjects;
};

#endif // CHIP_SYSTEM_CONFIG_POOL_USE_HEAP

#if CHIP_SYSTEM_CONFIG_POOL_USE_HEAP
template <typename T, unsigned int N>
using ObjectPool = HeapObjectPool<T>;
#else // CHIP_SYSTEM_CONFIG_POOL_USE_HEAP
template <typename T, unsigned int N>
using ObjectPool = BitMapObjectPool<T, N>;
#endif // CHIP_SYSTEM_CONFIG_POOL_USE_HEAP

enum class ObjectPoolMem
{
kStatic,
#if CHIP_SYSTEM_CONFIG_POOL_USE_HEAP
kDynamic
#endif // CHIP_SYSTEM_CONFIG_POOL_USE_HEAP
};

template <typename T, size_t N, ObjectPoolMem P>
class MemTypeObjectPool;

template <typename T, size_t N>
class MemTypeObjectPool<T, N, ObjectPoolMem::kStatic> : public BitMapObjectPool<T, N>
{
};

#if CHIP_SYSTEM_CONFIG_POOL_USE_HEAP
template <typename T, size_t N>
class MemTypeObjectPool<T, N, ObjectPoolMem::kDynamic> : public HeapObjectPool<T>
{
};
#endif // CHIP_SYSTEM_CONFIG_POOL_USE_HEAP

} // namespace chip
2 changes: 1 addition & 1 deletion src/system/SystemTimer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ namespace System {
*******************************************************************************
*/

BitMapObjectPool<Timer, CHIP_SYSTEM_CONFIG_NUM_TIMERS> Timer::sPool;
chip::ObjectPool<Timer, CHIP_SYSTEM_CONFIG_NUM_TIMERS> Timer::sPool;
Stats::count_t Timer::mNumInUse = 0;
Stats::count_t Timer::mHighWatermark = 0;

Expand Down
2 changes: 1 addition & 1 deletion src/system/SystemTimer.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ class DLL_EXPORT Timer

private:
friend class LayerImplLwIP;
static BitMapObjectPool<Timer, CHIP_SYSTEM_CONFIG_NUM_TIMERS> sPool;
static chip::ObjectPool<Timer, CHIP_SYSTEM_CONFIG_NUM_TIMERS> sPool;
static Stats::count_t mNumInUse;
static Stats::count_t mHighWatermark;

Expand Down

0 comments on commit 45c6b8b

Please sign in to comment.