Skip to content

nb architectural issues #15

Open
Open
@mqudsi

Description

@mqudsi

I believe there is a problem with the design of nb as it only allows for "one level" of asynchronicity, which is glossed over via the stubbed out definitions for the sample APIs in the documentation (such as serial_send and serial_receive).

If you were to actually flesh out those examples into real-world code, a problem arises wherein a nb function can really only decide that it would block once and only once. The moment stateful work commences that is predicated on the values that were passed in to the function, it becomes impossible to "early out" for the remainder of the function while still supporting a level of abstraction in which the function itself does not need to know anything about the caller.

For example, take the following pseudocode:

fn send_something(&mut self, bytes: &[u8]) -> nb::Result<(), !> {
    let result = self.already_sending_something.compare_exchange(false, true, Ordering:..);
    if result != Ok(false) {
        // Awesome, we avoided blocking when the sender was busy
        return Err(nb::Error::WouldBlock);
    }

    for i in 0..bytes.len() {
        // Start sending by loading this byte into the send register
        self.send_register.load(bytes[i]);

        // We could poll until the byte has been sent
        // while !self.send_register.is_empty() {};

        // But why don't we avoid blocking instead?
        if !self.send_register.is_empty() {
            return nb::Error::WouldBlock;
        }
    }

    return Ok(());
}

This code can be adapted to store i internally (saving state) so that the next time it is called after self.send_register.is_empty() returns false, it can pick up where it left off instead of starting over from zero, no problem. But how does it know that it is being called again by the same line of code/state?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions