Skip to content

Commit

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

We have too many pool allocators.

Previous PRs (#11428, #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 #9590)
- Add allocation selection (from #11371)
- Use this for `System::Timer` (complementing #11487)

- Factor out common code.
- Use a heap-allocated list to track heap-allocated objects.
- More unit tests.

Co-authored-by: Zang MingJie <zealot0630@gmail.com>
Co-authored-by: C Freeman <cecille@google.com>

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

#### Testing

Added heap versions of unit tests in TestPool. (A future PR will add
`System::Object`-style statistics and re-unify most of these tests.)

CI should show `.bss` decreases corresponding to increases in #11487.
  • Loading branch information
kpschoedel authored Nov 19, 2021
1 parent dcca930 commit 1adaf7a
Show file tree
Hide file tree
Showing 5 changed files with 564 additions and 72 deletions.
67 changes: 64 additions & 3 deletions src/lib/support/Pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

namespace chip {

namespace internal {

StaticAllocatorBitmap::StaticAllocatorBitmap(void * storage, std::atomic<tBitChunkType> * usage, size_t capacity,
size_t elementSize) :
StaticAllocatorBase(capacity),
Expand All @@ -46,7 +48,7 @@ void * StaticAllocatorBitmap::Allocate()
{
if (usage.compare_exchange_strong(value, value | (kBit1 << offset)))
{
mAllocated++;
IncreaseUsage();
return At(word * kBitChunkSize + offset);
}
else
Expand All @@ -70,7 +72,7 @@ void StaticAllocatorBitmap::Deallocate(void * element)

auto value = mUsage[word].fetch_and(~(kBit1 << offset));
nlASSERT((value & (kBit1 << offset)) != 0); // assert fail when free an unused slot
mAllocated--;
DecreaseUsage();
}

size_t StaticAllocatorBitmap::IndexOf(void * element)
Expand All @@ -83,7 +85,7 @@ size_t StaticAllocatorBitmap::IndexOf(void * element)
return index;
}

bool StaticAllocatorBitmap::ForEachActiveObjectInner(void * context, Lambda lambda)
bool StaticAllocatorBitmap::ForEachActiveObjectInner(void * context, bool lambda(void * context, void * object))
{
for (size_t word = 0; word * kBitChunkSize < Capacity(); ++word)
{
Expand All @@ -101,4 +103,63 @@ bool StaticAllocatorBitmap::ForEachActiveObjectInner(void * context, Lambda lamb
return true;
}

#if CHIP_SYSTEM_CONFIG_POOL_USE_HEAP

HeapObjectListNode * HeapObjectList::FindNode(void * object) const
{
for (HeapObjectListNode * p = mNext; p != this; p = p->mNext)
{
if (p->mObject == object)
{
return p;
}
}
return nullptr;
}

using Lambda = bool (*)(void *, void *);
bool HeapObjectList::ForEachNode(void * context, bool lambda(void * context, void * object))
{
++mIterationDepth;
bool result = true;
bool anyReleased = false;
HeapObjectListNode * p = mNext;
while (p != this)
{
if (p->mObject != nullptr)
{
if (!lambda(context, p->mObject))
{
result = false;
break;
}
}
if (p->mObject == nullptr)
{
anyReleased = true;
}
p = p->mNext;
}
--mIterationDepth;
if (mIterationDepth == 0 && anyReleased)
{
// Remove nodes for released objects.
p = mNext;
while (p != this)
{
HeapObjectListNode * next = p->mNext;
if (p->mObject == nullptr)
{
p->Remove();
delete p;
}
p = next;
}
}
return result;
}

#endif // CHIP_SYSTEM_CONFIG_POOL_USE_HEAP

} // namespace internal
} // namespace chip
Loading

0 comments on commit 1adaf7a

Please sign in to comment.