-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Make SyncDroplessArena allocations thread-local in the fast path #61873
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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_arena
to use.r? @eddyb