Make SyncDroplessArena allocations thread-local in the fast path#61873
Make SyncDroplessArena allocations thread-local in the fast path#61873Zoxc wants to merge 2 commits intorust-lang:masterfrom
Conversation
|
The job Click to expand the log.I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
|
I don't know how any of this concurrent code works, sorry! (Or rather, why it might be safe) cc @rust-lang/compiler Is anyone else comfortable with concurrent data structures and willing to review? |
|
I'll review it and/or get @aturon to do so =) |
|
ping from triage @nikomatsakis @aturon any updates on this? |
|
Hey @Dylan-DPC, I plan to review this one, however at the moment I'm getting up to speed on the concurrency approach in general. |
|
thanks. No issues. |
|
I do not |
|
ping from triage @stjepang, could you provide comment on this PR? |
| pub fn clear(&mut self) { | ||
| self.lock.get_mut().clear(); | ||
| fn grow(&self, n: usize, chunks: &mut Vec<TypedArenaChunk<T>>) { | ||
| unsafe { |
There was a problem hiding this comment.
Would be great if these large unsafe { .. } blocks would have comments justifying their soundness.
(Applies throughout the PR.)
|
Ping from triage. @aturon any updates on this? Thanks |
|
Waiting for a review from @rust-lang/compilers |
| impl<T> CurrentChunk<T> { | ||
| #[inline] | ||
| fn align(&self, align: usize) { | ||
| let final_address = ((self.ptr.get() as usize) + align - 1) & !(align - 1); |
There was a problem hiding this comment.
use https://doc.rust-lang.org/std/primitive.pointer.html#method.align_offset instead of handrolling the computation
| self.lock.get_mut().clear(); | ||
| fn grow(&self, n: usize, chunks: &mut Vec<TypedArenaChunk<T>>) { | ||
| unsafe { | ||
| let (chunk, mut new_capacity); |
There was a problem hiding this comment.
move chunk declaration to initialization site
| fn grow(&self, n: usize, chunks: &mut Vec<TypedArenaChunk<T>>) { | ||
| unsafe { | ||
| let (chunk, mut new_capacity); | ||
| if let Some(last_chunk) = chunks.last_mut() { |
There was a problem hiding this comment.
The statements in the Some block of this if let deserve some documenting comments.
|
|
||
| current.align(align); | ||
|
|
||
| let future_end = intrinsics::arith_offset(current.ptr.get(), bytes as isize); |
There was a problem hiding this comment.
why not use https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_offset here? Intrinsics should not be used except in their wrapper code
There was a problem hiding this comment.
Alternatively you can use offset_from to compute the offset between end and ptr and see if that is bigger than bytes. I think I'd prefer it that way around.
There was a problem hiding this comment.
Oh, we stabilized this intrinsic? That seems unfortunate as it can be used to create invalid pointers (which are UB in C).
There was a problem hiding this comment.
It's not stable. and it's still unsafe, so if you think there are problems with it, please raise them on the tracking issue (#41079). wrapping_offset_from is safe.
| let ptr = current.ptr.get(); | ||
| // Set the pointer past ourselves | ||
| current.ptr.set( | ||
| intrinsics::arith_offset(current.ptr.get(), bytes as isize) as *mut u8, |
There was a problem hiding this comment.
since we just grew the thing, we can now use ptr::offset, right?
|
Ping from Triage: closing due to inactivity. Please re-open if there are updates. @Zoxc |
This works by having a thread local chunk to allocate from and a global list of chunks for
in_arenato use.r? @eddyb