-
-
Notifications
You must be signed in to change notification settings - Fork 216
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
Added MemoryLimiter and other classes etc. #652
Conversation
🤖 Upon creation, pull request description does not have a link to an issue. If there is a related issue, please add it to the description using any of the supported formats. |
@gavv Please give a quick early review on MemoryLimiter. Does the tracking need to be atomic? |
I think I've answered my own question. Yes, I suppose, as it's shared across various arenas and pools. |
Yep, it should be atomic, and ideally lock free. I guess it would be enough to use core::Atomic or core::AtomicOps. We likely need to get rid of would_allow because it's usage will be always a race. Otherwise, the class looks fine! |
Oh, also %zu is not portable, please use %lu with a cast to ulong. |
OK. I've used it elsewhere in the code as well. |
See my approach now. |
OK. I should have kept this in draft. I've just added the LimitedArena, LimitedPool, and could use your thoughts on it and a few things. Not yet added tests. |
Some notes:
|
Quick q about... how to approach LimitedPool.
|
|
I see some commits, please ping me when it's ready for review :) |
Yea. Sorry. Small tidy ups are remaining and a few more tests. |
I've looked at the implementation and have small suggestion about IPool and IArena interface. size_of + overhead / object_size + overhead looks a bit too low level, because the caller needs to know that there is "payload" size and "overhead" size. The caller also should assume that the overhead is constant (same for all allocations), which by the way may not be true when arena applies alignment? Instead of that, I think it would be a bit simpler if the caller will operate with just one "allocation size", which includes payload + overhead. For IPool, it can be one method, e.g.: virtual size_t allocation_size() = 0; We can remove object_size() since it's not really used and keep only allocation_size() which takes overhead into account. For IArena, we'd still need 2 methods, but they will both include payload + overhead: //! Computes how much bytes will be actually allocated if allocate() is called with given size.
//! Covers all internal overhead, if any.
virtual size_t compute_allocated_size(size_t size) = 0;
//! Returns how much bytes was allocated for given pointer returned by allocate().
//! Covers all internal overhead, if any.
//! Returns same value as computed by compute_allocated_size(size).
virtual size_t allocated_size(void*) = 0; Feel free to change naming and comments of course. What do you think? |
Thanks for update, I've posted a few more comments. |
It does make sense. I did think about something similar to this initially - should have suggested. |
@@ -54,8 +54,7 @@ class IPool { | |||
//! Placement new for core::IPool. | |||
//! @note | |||
//! nothrow forces compiler to check for NULL return value before calling ctor. | |||
inline void* operator new(size_t size, roc::core::IPool& pool) throw() { | |||
roc_panic_if_not(size <= pool.object_size()); |
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.
@gavv
Note: I had to remove this only good use of object_size() as well.
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 think we can add size
parameter to allocate(). Implementation can then check that requested size fits within slot size. This way we can be sure that any allocation on pool is safe (no matter via new or directly via allocate).
const bool is_owner = chunk->owner == this; | ||
|
||
if (!is_owner) { | ||
if (AtomicOps::load_seq_cst(flags_) & HeapArenaFlag_EnableGuards) { |
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 had to remove num_guard_failures_++;
from here, because this method is const. Would you rather have the member variable as mutable?
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 makes sense to make it mutable. I'd say it's not part of the logical object state.
ffb4683
to
2533ecd
Compare
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.
Thanks for update, a few more issues remaining.
b2c9872
to
516ec84
Compare
da1a8c4
to
11b3710
Compare
Thank you! Looks good! I've created a PR with small refactoring of guard flags in heap arena and slap pool (not directly related to this PR). You can take a look if you wish: #700 |
Why
For #610
What
Testing
There are tests.