-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merge SystemPool and support/Pool #9748
Conversation
@mspang , The recursive mutex comes about with the original object pool design which was more than an allocator: it also allowed the sdk to iterate over all allocated objects in the pool. So instead of properly tracking state, we shoe-horned this iteration facility into an allocator to allow the sdk to do a foreach on all objects of a given class without actually having to actively track anything. When we moved to the heap implementation, this became a very difficult problem. And now to do an object release or mutation in the middle of the foreach loop, you need the recursive mutex. Is there a way that we can remove the need to iterate over all pool objects in the first place? This would make things much, much simpler. |
I would agree with that statement. This locks the set (why a set?), then makes a copy of it, but keeps the original lock while iterating the copy. Why did we make the copy? Because a reentrant mutex doesn't make reentrant modification safe. Why hold the lock while working with a copy? There's no logic to this. |
The iterator of I'll change it such that it only lock when creating the copy, and use normal mutex instead of a recursive mutex. |
The copy becomes invalid as soon as the mutex is released. |
I'm not sure it's worth writing that up until we have better design consensus. |
|
||
#include <lib/core/CHIPConfig.h> | ||
|
||
#if CHIP_SYSTEM_CONFIG_POOL_USE_HEAP |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we refactor code to clean out "#if CHIP_SYSTEM_CONFIG_POOL_USE_HEAP" in SystemPoolHeap.h ? since this file only contains heap based implementation. The #if check should be made in SystemPool.h
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer this way rather that
#if CHIP_SYSTEM_CONFIG_POOL_USE_HEAP
#include <Impl_A>
#else
#include <Impl_B>
#endif
The proposing PR is more robust, because people may mistakenly include wrong headers, compiling wrong code, Which may hard to troubleshot.
|
||
#include <lib/core/CHIPConfig.h> | ||
|
||
#if !CHIP_SYSTEM_CONFIG_POOL_USE_HEAP |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file suppose to only implement non heap logic, CHIP_SYSTEM_CONFIG_POOL_USE_HEAP is not needed
No, the current implementation use std::mutex, it is not the original System Pool design, we should change back to std::mutex |
|
||
private: | ||
std::recursive_mutex mutex; | ||
std::set<T *> mObjects; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why std::set
? Seems like a std::list
would be a more appropriate type here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be very hard to implement ReleaseObject
if std::list
is used here. If using a intrusive_list
, It will requires that the object is derived from a base class of intrusive_list<T>
, We may not want to have this limitation.
src/system/SystemPoolHeap.h
Outdated
template <typename Function> | ||
bool ForEachActiveObject(Function && function) | ||
{ | ||
std::lock_guard<std::recursive_mutex> lock(mutex); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of making this a recursive mutex, an alternative would be to alter the signature of Function
to provide an inout arg that indicates if the item should be deleted. This then allows for clamping down what Function
can do (which is not invoke ReleaseObject
or CreateObject
calls), and consequently, avoiding the need to make this a recursive mutex and still safely delete the list item while iterating.
This also avoids the need to make a copy of the set.
For those, a link in the description is sufficient not a copy of the whole text. But it is definitely a pain that this works so poorly in GitHub. |
Release(); | ||
} | ||
|
||
#if CHIP_SYSTEM_CONFIG_USE_LWIP | ||
void TCPEndPoint::DeferredFree(ReleaseDeferralErrorTactic aTactic) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DeferredRelease needs to be used for all Lwip implementations, we should move this back to SystemPool.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why ? We will have lots of potential usages which do not need DeferredFree
, Only TCPEndpoint
and UDPEndpoint
need it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because DeferredRelease is a variant of Release in case the owner want to keep the object after release until the end of current event loop. This is not TCPEndPoint, UDPEndpoint, EndPointBasis specific. Otherwise, each object need to use this feature will have to implement a copy of this function by itself in future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, think it another way, it doesn't defer the release of the object, it is deferring the Release
calls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the benefit to refactor this function out of SystemPool? What gains we get if each user of this feature need to implement a copy of this feature by itself.
#endif // !CHIP_SYSTEM_CONFIG_USE_LWIP | ||
} | ||
|
||
#if CHIP_SYSTEM_CONFIG_USE_LWIP | ||
void UDPEndPoint::DeferredFree(ReleaseDeferralErrorTactic aTactic) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DeferredRelease needs to be used for all Lwip implementations, we should move this back to SystemPool.
9a9ceae
to
00e02ab
Compare
00e02ab
to
a0cfe47
Compare
a0cfe47
to
479af54
Compare
Size increase report for "gn_qpg-example-build" from 3647c29
Full report output
|
Size increase report for "esp32-example-build" from 3647c29
Full report output
|
This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. |
This stale pull request has been automatically closed. Thank you for your contributions. |
Problem
We have too many pool implementation.
Change overview
There are 3 changes:
Add a PostLambda to post a generic lambda into system event queue #9678
Add a PostLambda to post a generic lambda into system event queue. This will decouple system object from network endpoints (TCPEndpoint, UDPEndpoint).
There is several limitation of the lambda
Unify SystemPool and lib/support/Pool #9590
Unify the interface of system/SystemPool and lib/support/pool. This PR change the interface of SystemPool to match lib/support/Pool. The pool provides following interface functions:
And also provides statistics interface:
Following features are decoupled from the pool implementation:
DeferredRelease
: this feature should be orthogonal to pool implementation, the target class should implement it by itself.Files changes:
Removed
Implementation on platforms with heap (POSIX):
Implementation on platforms w/o heap (Embedded):
Statistics:
Select implementation based on pre-defined macro
Merge SystemPool and support/Pool #9748 (this PR)
Remove
lib/support/Pool
, migrate all its usage tosystem/SystemPool
Testing
Verified using unit tests