The Book

A Guide to The Kernel Structures

API

The Book

The Kernel is an Actor system with two main Actor types: Queues, represented as ring buffers of memory slices; and Tasks, cpu processing atomic ports. Queues could be two types: Publisher, who holds writer cursors; and Subscriber, who holds reader cursors. Tasks represented as Rust LLVM tasks and/or CPS interpreter tasks. There is two special tasks: InterCore task spawned at any enabled cores; and CPS interpreter task of The Kernel Maintanance Shell is spawned at boot core, which also runs Console and WebSocket system IO. During system lifetime different CPS and Rust tasks could be spawned.

Besides Queues and Tasks there is also Timers and other system IO tasks such as Network or Files. There are other entities such as Cores which are binded to cpus and run the task scheduler loops.

The entire Virtual Machine is a set of Cores.

Publisher

pub struct Publisher<T> { ring: Arc<RingBuffer<T>>, next: Cell<Sequence>, cursors: UncheckedUnsafeArc<Vec<Cursor>>, }

Subscriber

pub struct Subscriber<T> { ring: Arc<RingBuffer<T>>, token: usize, next: Cell<Sequence>, cursors: UncheckedUnsafeArc<Vec<Cursor>>, }

Channel

The Channel represents a InterCore node component. With one writer cursor and multiple readers equals to number of cores.

pub struct Channel { publisher: Publisher<Message>, subscribers: Vec<Subscriber<Message>>, }

Memory

The Memory represents avaiable number of Pubishers and Subscribers on core. This value is passed as shared to each task created on core.

pub struct Memory<'a> { publishers: Vec<Publisher<Value<'a>>, subscribers: Vec<Subscriber<Value<'a>>>, }

Scheduler

The Scheduler represents the processor core and known to be BSP or bootstrap processor and application processors AP. The default BSP core contains in it's io Console and WebSocket IO selectors. It means BPS gave it's loop to kernel, while AP processors don't (IO queue is empty). There are InterCore messages that can add or remove arbitrary IO selectors to Scheduler for custom configurations.

pub struct Scheduler<'a> { pub tasks: Vec<T3<Job<'a>>>, pub bus: Channel, pub queues: Memory<'a>, pub io: IO, }

Boot

The boot process composed of two functions: 1) creating the bus topology and 2) parking scheduler instances to cores. By default star topology is used: where any core can talk to each other. The BPS processor is allocated for maintanance shell and other custom IO operations such as logging, stats, backup or other non real-time operations. By calling run0 function parks the BSP scheduler while other core are parked with run call.

pub fn simple<'a>(sched_num: usize) -> Vec<Scheduler<'a>>; let mut scheds: Vec> = Vec::new(); for i in 0..sched_num { scheds.push(Scheduler::with_channel(i)); } scheds } pub fn park<'a>(mut scheds: Vec<Scheduler<'a>>) -> Scheduler<'a> { let sz = scheds.len(); for id in 1..sz { if let Some(mut core) = scheds.pop() { unsafe { spawn_on(id, move || core.run()); } } } scheds.pop().expect("No BSP") } pub fn main() { park(simple(16)).run0(input); }

Looper

Each AP scheduler run loop has several implementations but the default is Weighted Fair Queueing (WFQ) controlled by three parameters: 1) Bus 2) IO and 3) Tasks poll quantums. Inside the loop scheduler performs each flow within a given quantum. These parameters could be changed with QoS InterCore protocol bus message.

pub fn run(&mut self) { loop { self.poll_bus(self.bus_quantum); self.poll_io(self.io_quantum); self.poll_tasks(self.tasks_quantum); self.hibernate(); } }

The BPS run loop is a bit more complex as it needs to run Shell Task and route all system IO messages to that task with InterCore Exec protocol message.

IO

pub struct IO { tokens: usize, events: Events, poll: Poll, selectors: Vec<Selector>, slots: Vec<usize>, running: bool, polled: usize, }

Task

pub trait Task<'a> { fn init(&'a mut self, input: Option<&'a str>); fn exec(&'a mut self, input: Option<&'a str>); fn finalize(&'a mut self); fn poll(&'a mut self, c: Context<'a>) -> PollCtx<'a>, Error>; }

CpsTask

pub struct CpsTask<'a> { interpreter: Interpreter<'a>, ast: Option<&'a AST<'a>>, }