92 lines
2.3 KiB
Rust
92 lines
2.3 KiB
Rust
//! 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<CapSlot> {
|
|
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]);
|
|
}
|