faern / oneshot

Oneshot Rust channel working both in and between sync and async environments
Apache License 2.0
80 stars 9 forks source link

Optimize waker allocation size when type is statically known #4

Open faern opened 4 years ago

faern commented 4 years ago

When async support was introduced and the Thread instance was replaced with a ReceiverWaker, heap usage went from 8 to 24 bytes for this object. This is not a lot, but would be nice to be able to avoid it. If we know statically whether the channel should unpark a channel or wake a task it can still allocate a Thread or Waker instead of the generic ReceiverWaker.

Since it would be nice to still be able to store senders and receivers that send to both to sync threads and async tasks in the same containers it is also a requirement that senders can be generic the way they currently are.

Proposed solution (EARLY DRAFT):

pub trait WakerMode {
    type Waker;

    alloc_waker() -> *mut Waker;
}

pub struct Generic;
pub struct Sync;
pub struct Async;

pub struct Sender<T, Mode: WakerMode = Generic> {...}
pub struct Receiver<T, Mode: WakerMode = Generic> {...}

The goal is to make the generic channel work as now: Can receive both sync and async and cost 24 bytes for the waker. But allow a special Receiver<T, Sync> that will only allocate an 8 byte Thread for unparking.