Skip to content

Conversation

@darkwisebear
Copy link
Contributor

  • Add Producer trait
  • Add as_mut_ptr to SampleMaybeUninit

* Add Producer trait
* Add as_mut_ptr to SampleMaybeUninit
///
/// The caller has to make sure to initialize the data in the buffer.
/// Reading from the received pointer before initialization is undefined behavior.
fn as_mut_ptr(&mut self) -> *mut T;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which exact problem we are solving with this ? This is quite risky API since beside description, we hope user will know T may not be read really (and since as_mut_ptr is common in Rust codebases, it may be easy to miss-spot in review ).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This enables initializing the sample pointer member-by-member. It becomes important in cases where you want your produce to put the result directly into the shared memory area without first having to initialize a local instance of the type T.

This becomes important when we're talking about really big data structures. In this case, you might either not have (or want to spend) the memory to build the type internally, and copying itself also may take a non-negligible amount of time. In order to safe this, one might want to create an uninitialized sample, use this method to obtain a pointer, and then initialize the type piece by piece by write-only accesses. Since we hand back a pointer, this method can even be safe since working with a pointer is unsafe anyway.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes this is placement new missing in API. So I would say we have two use case

  • default placement init for large types
  • non default placement init for large types (ie data comming from some other entity ie, hw or cpp code)

For the first I would try standarize approach ie:

pub trait PlacementDef {
    unsafe fn placement_def(ptr: *mut Self);
}

and then in SampleMutUninit

fn write_in_place<T: PlacementDef>(&mut self) {
    unsafe {
        T::placement_def(ptr);
    }
}

For the second, since it mimics MaybeUnint api with as_mut_ptr, it shall be fine. But maybe, the SampleMutUninit<T> shall really hold(mandate) MaybeUninit<T> instead and our api shall return ref to it ie, fn data(&mut self) -> &MaybeUninit<T>. From this point, user will get other abilities.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants