//! Threads, processes, time and debug output. use super::{call0, raw, slot_of}; use types::address::{EntryPoint, StackPointer}; use types::bounded::CapSlot; use types::budget::Limits; use types::id::ProcessId; use types::syscall_abi::*; use types::time::Ticks; // ---- threads, processes, time ---- pub fn exit() -> ! { let _ = call0(SYS_EXIT); // The kernel does not return from an exit. loop { core::hint::spin_loop(); } } pub fn exit_thread() -> ! { let _ = call0(SYS_EXIT_THREAD); loop { core::hint::spin_loop(); } } pub fn yield_now() { let _ = call0(SYS_YIELD); } /// Stops the machine. Needs a SystemControl capability; without one the /// call fails and this spins, since there is nothing sensible to return. pub fn halt(control: CapSlot) -> ! { let _ = raw(SYS_HALT, [control.value() as usize, 0, 0, 0, 0, 0]); loop { yield_now(); } } pub fn get_time() -> Ticks { Ticks::from_raw(call0(SYS_GET_TIME).map_or(0, |r| r[1]) as u64) } pub fn get_process_id() -> ProcessId { ProcessId::from_raw(call0(SYS_GET_PROCESS_ID).map_or(0, |r| r[1]) as u16) } /// The new process's `limits` come out of this process's own budget. pub fn create_process(create_cap: CapSlot, limits: Limits) -> Option { slot_of(raw( SYS_CREATE_PROCESS, [ create_cap.value() as usize, limits.pages, limits.endpoints, limits.notifications, limits.regions, 0, ], )) .ok() } /// `arg` arrives in the new thread's `a0` (see `libkos::start`). pub fn spawn_thread(entry: EntryPoint, stack: StackPointer, arg: usize) -> usize { raw(SYS_SPAWN_THREAD, [entry.raw(), stack.raw(), arg, 0, 0, 0]).map_or(NONE, |r| r[1]) } pub fn spawn_thread_in(process_cap: CapSlot, entry: EntryPoint, stack: StackPointer, arg: usize) -> usize { raw( SYS_SPAWN_THREAD_IN, [ process_cap.value() as usize, entry.raw(), stack.raw(), arg, 0, 0, ], ) .map_or(NONE, |r| r[1]) } pub fn kill(process_cap: CapSlot) -> bool { raw(SYS_KILL, [process_cap.value() as usize, 0, 0, 0, 0, 0]).is_ok() } pub fn debug_putchar(console: CapSlot, byte: u8) { let _ = raw(SYS_DEBUG_PUTCHAR, [console.value() as usize, byte as usize, 0, 0, 0, 0]); }