47 lines
1.3 KiB
Rust
47 lines
1.3 KiB
Rust
|
|
type WorkerId = usize;
|
||
|
|
type ActorId = usize;
|
||
|
|
|
||
|
|
struct Actor(u8);
|
||
|
|
|
||
|
|
const MESSAGE_RING_BUFFER_SIZE: usize = 4096;
|
||
|
|
const LOCAL_ARENA_BUFFER_SIZE: usize = 262144;
|
||
|
|
// hitting the maximum would imply reading nothing but length prefixes from the ring channel
|
||
|
|
const MAX_MESSAGES_PER_DRAIN: usize = MESSAGE_RING_BUFFER_SIZE / 4;
|
||
|
|
|
||
|
|
use crate::channel::spsc::Consumer as RingBuffer;
|
||
|
|
|
||
|
|
#[repr(align(64))]
|
||
|
|
struct LocalArena {
|
||
|
|
data: [u8; LOCAL_ARENA_BUFFER_SIZE],
|
||
|
|
offsets: [u32; MAX_MESSAGES_PER_DRAIN],
|
||
|
|
}
|
||
|
|
struct Worker {
|
||
|
|
id: WorkerId,
|
||
|
|
inbox_rings: Vec<RingBuffer<MESSAGE_RING_BUFFER_SIZE>>,
|
||
|
|
arena: LocalArena,
|
||
|
|
actor_table: Vec<Actor>,
|
||
|
|
}
|
||
|
|
|
||
|
|
impl Worker {
|
||
|
|
pub fn run(&mut self) {
|
||
|
|
// cannot overflow the arena buffer
|
||
|
|
debug_assert!(self.inbox_rings.len() * MESSAGE_RING_BUFFER_SIZE < LOCAL_ARENA_BUFFER_SIZE);
|
||
|
|
|
||
|
|
loop {
|
||
|
|
// drain messages into our local memory arena buffer
|
||
|
|
for ring in &self.inbox_rings {
|
||
|
|
// logic here
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
struct BucketBuffer {
|
||
|
|
// Pre-allocated array of slices. Max 64K actors, resize if needed.
|
||
|
|
// bucket[i] contains indices of messages for actor i.
|
||
|
|
buckets: Vec<Vec<u8>>, // Or flat Vec with head/tail if arena-allocated
|
||
|
|
actor_order: Vec<ActorId>, // Which actors have messages (for iteration)
|
||
|
|
}
|