io: Scatter/gather / zero-copy APIs
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 25/100
- Issue type
- Feature
- Clarity
- Needs clarification
- Activity status
- Stale
- Tech stack
- rust
- Domain
- embedded-iot, networking
Research direction
Start by reviewing the current embedded-io 1.0 traits, the std::io read_vectored and write_vectored APIs, and embedded-hal issue 566. Compare the simple vectored and zero-copy proposals with the linked Godbolt example and consider their relevance to TCP and UDP. Done means the compatibility question and scope have a maintainer-backed decision.
Written by the indexing model from the issue text.
Description
Checking with the Ariel OS team on whether there's anything amiss in embedded-io, the request for vectored I/O came up – revolving around "Are those APIs suitable for avoiding needless intermediate copies?".
There is some vagueness in what this entails; some aspects that seem important are:
- Doing the equivalent of
std::io::Write::write_vectoredis almost trivial because we write to &mut self (so there's no danger of interleaving), and barring optimizations of using a single syscall, awrite_vectoredcan be provided by calling single writes. - Same goes for a simple
read_vectoredthat merely writes to multiple caller-allocated buffers. - A more powerful form of a vectored read (call it zero-copy read) would produce an iterator view of the data as it sits eg. in some TCP buffer; that data may be non-contiguous eg. when straddling a ring buffer's wraparound. That would not (as the std::io form) populate the moral equivalent of
&mut [&mut [u8]], but would return roughly animpl Iterator<Item = &[u8]>. - There might be a powerful form of the Write as well, where some longer-lived type (something something
AsRef<[u8]>) is sent to the Writer, which it may then consume at the rate of the device writing, but there's some uncertainty about whether that is relevant.
The pressing first point, in my current context of https://github.com/rust-embedded/embedded-hal/issues/566 (embedded-io 1.0) is: Would any of that need breaking changes if we released the current main as 1.0?
I think not, because:
- For the simple forms, a
read_vectored/write_vectoredcould be added to the trait at a later time as provided methods. - For the zero-copy read, a user implementing an application on a generic embedded_io::Read implementation could not know whether vectored reads are available -- for all they know, this would most likely come from a byte-oriented device that has no buffers of their own. (From that PoV, those who use embedded-io as the interface to a TCP connection are the weird ones out because their reads are actually buffered internally in the network stack).
Nonetheless, an interface could be added as a provided method: The user would provide a fallback buffer to read into, which is what the provided method would populate through a regular read call. This may look wasteful in light of use with zero-copy-capable backends (after all, the user may not be motivated by the CPU cycles copying takes, but because their stack is limited), but an example implementation at https://godbolt.org/z/heEs3jG64 shows that through monomorphization, if the concrete Read impl's method never produces the "I wrote to your buffer" outcome, that allocation is dead code, and gets eliminated at build time. - I expect that any shenanigans with powerful Write would work with provided methods that just instantly block on writing the data; at worst, they'd need an associated type, and would thus depend on the stabilization of https://github.com/rust-lang/rust/issues/29661.
So my questions to the community / maintainers are:
- Is this something you'd like to see considered / added / would review PRs for?
Note that while this is primarily about embedded-io now, it may also help us build the equivalent tools for embedded-nal's UDP side. (Its TCP side is what'd profit from these methods already). - Do you agree that anything that'd be added could be added after an 1.0 release, as argued above?
CC'ing @kaspar030 with whom I've discussed this for the Ariel use cases.
- Dominant language
- Rust
- Stars
- 2.7k
- Forks
- 282
- PR merge metrics
- No merged PRs in 30d
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from rust-embedded/embedded-hal
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
rust-embedded/embedded-hal#742 · 1 comment ·
-
Difficulty 5/5 Over a week Newbie friendliness 30/100
rust-embedded/embedded-hal#747 · 5 comments · 1 reaction ·
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
rust-embedded/embedded-hal#746 · 2 comments · 1 reaction ·
-
Difficulty 4/5 3-5 days Newbie friendliness 48/100
rust-embedded/embedded-hal#745 · 1 reaction ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 55/100
rust-embedded/embedded-hal#744 · 1 comment ·
All issues in rust-embedded/embedded-hal
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
kwakseongjae/auto-hwp#319 ·
-
area:cli bug filter-quality good first issue priority:medium
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
Difficulty 1/5 Under an hour Newbie friendliness 72/100
bevyengine/bevy#25861 ·
-
comp-datalake
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
ClickHouse/ClickHouse#121222 ·
-
enhancement remote
Difficulty 2/5 1-3 hours Newbie friendliness 68/100