-
Notifications
You must be signed in to change notification settings - Fork 27
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
Feature/generic stream #414
Conversation
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.
Nice work. Let me know what you think about the two bigger things (MaybeUninit
and the genericism/light-weight queue items).
src/net/data_stream.rs
Outdated
format, | ||
offset: 7, | ||
sequence_number, | ||
buffer: unsafe { buffer.assume_init() }, |
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 wonder whether it would be better to follow through with the notion that this is uninitialized data. I would not allow the closure (to add()
) to read stale/previous data in the buffers.
The closure is the recipient of the "out-pointer" in https://doc.rust-lang.org/std/mem/union.MaybeUninit.html#out-pointers. And the closure will be doing unsafe stuff in general.
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 is not a MaybeUninit
structure, but rather a heapless::pool::Box<T, Uninit>
. The only way to get a Box<T, Init>
is to call Box::init(t: T)
, where a copy from t
-> inner data is performed. If we actually did that, we'd have to enforce a 1KB copy (of zero'd data) into the buffer whenever pulling a buffer out of the pool (e.g. in the high prio task). I wanted to avoid that overhead, since we never read the buffer anyways.
Edit: While the above is true, we could still follow-through with using a MaybeUninit<[u8; FRAME_SIZE]>
type in the pool. Then we can initialize it with MaybeUninit::uninit()
and use the concept of out-pointers you referenced. I don't know if this would work, but I'll definitely look into 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.
Are you sure? The only example I'm aware of is this: https://github.com/stm32-rs/stm32l4xx-hal/blob/master/examples/rtic_frame_serial_dma.rs#L92
DMAFrame::new()
has a MaybeUninit::uninit()
member. The dma_buf.init()
(ptr::write(...)
) would copy uninitialized data? I suspect that this is not the case and this is actually the pattern we also want to follow 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.
core::ptr::write()
is just a call to memcpy underneath. Thus, even if we have a MaybeUninit::uninit()
object, we're still copying the entire MaybeUninit structure, which contains the underlying data buffer (it's a union type). When memcpy-ing a union, you have to memcpy the whole size of the union, which in this case is the 1024 bytes for the buffer.
Check out godbolt for the compiler output: https://godbolt.org/z/n8r6EexK6 - both do a memcpy of 1024 bytes.
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.
Hmm. Right.
Would be interesting to discuss with @korken89 what the intended usage pattern is here without assume_init.
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.
Nice
bors r+ |
Build succeeded: |
This PR fixes #385 by improving the semantics by which streams are generated. Specifically, serialization format is now application-defined and data is only copied once.
TODO: