Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/syscall/abi/registry/mk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub(super) const ENTRIES: &[AbiEntry] = &[
e(b"MKAR", SyscallNumber::MkArgs, "MkArgs"),
e(b"MTSP", SyscallNumber::MkThreadSpawn, "MkThreadSpawn"),
e(b"MYLD", SyscallNumber::MkYield, "MkYield"),
e(b"MSLP", SyscallNumber::MkSleepMs, "MkSleepMs"),
e(b"MTMS", SyscallNumber::MkTimeMillis, "MkTimeMillis"),
e(b"MTRT", SyscallNumber::MkTimeRtc, "MkTimeRtc"),
e(b"MBAT", SyscallNumber::MkBatteryStatus, "MkBatteryStatus"),
Expand Down
1 change: 1 addition & 0 deletions src/syscall/contract/cap_table/mk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub(super) fn check(caps: &CapabilityToken, number: SyscallNumber) -> Option<boo
SyscallNumber::MkExit
| SyscallNumber::MkPidAlive
| SyscallNumber::MkYield
| SyscallNumber::MkSleepMs
| SyscallNumber::MkTimeMillis
| SyscallNumber::MkTimeRtc
| SyscallNumber::MkBatteryStatus
Expand Down
1 change: 1 addition & 0 deletions src/syscall/dispatch/router/microkernel_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub(super) fn matches(nr: SyscallNumber) -> bool {
| MkArgs
| MkThreadSpawn
| MkYield
| MkSleepMs
| MkTimeMillis
| MkTimeRtc
| MkBatteryStatus
Expand Down
4 changes: 3 additions & 1 deletion src/syscall/microkernel/dispatch/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ use crate::syscall::microkernel::memory::{sys_mmap, sys_munmap};
use crate::syscall::microkernel::numbers::*;
use crate::syscall::microkernel::proc_output::sys_proc_output;
use crate::syscall::microkernel::process::{
sys_args, sys_exit, sys_getpid, sys_pid_alive, sys_spawn, sys_thread_spawn, sys_yield,
sys_args, sys_exit, sys_getpid, sys_pid_alive, sys_sleep_ms, sys_spawn, sys_thread_spawn,
sys_yield,
};
use crate::syscall::microkernel::procstat::sys_proc_stat;
use crate::syscall::microkernel::time::{sys_time_millis, sys_time_rtc};
Expand All @@ -39,6 +40,7 @@ pub(super) fn handle(nr: u64, a: Args) -> Option<i64> {
SYS_ARGS => sys_args(a.a0, a.a1 as usize),
SYS_THREAD_SPAWN => sys_thread_spawn(a.a0, a.a1),
SYS_YIELD => sys_yield(),
SYS_SLEEP_MS => sys_sleep_ms(a.a0),
SYS_TIME_MILLIS => sys_time_millis(),
SYS_TIME_RTC => sys_time_rtc(a.a0),
SYS_BATTERY_STATUS => sys_battery_status(),
Expand Down
1 change: 1 addition & 0 deletions src/syscall/microkernel/numbers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub const SYS_GETPID: u64 = tag4(b"MGPD");
pub const SYS_ARGS: u64 = tag4(b"MKAR");
pub const SYS_THREAD_SPAWN: u64 = tag4(b"MTSP");
pub const SYS_YIELD: u64 = tag4(b"MYLD");
pub const SYS_SLEEP_MS: u64 = tag4(b"MSLP");
pub const SYS_TIME_MILLIS: u64 = tag4(b"MTMS");
pub const SYS_TIME_RTC: u64 = tag4(b"MTRT");
pub const SYS_BATTERY_STATUS: u64 = tag4(b"MBAT");
Expand Down
21 changes: 21 additions & 0 deletions src/syscall/microkernel/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,27 @@ pub fn sys_yield() -> i64 {
0
}

// Deschedule the caller for `ms` milliseconds. Unlike yield, which leaves
// the task runnable and so keeps a busy backoff loop pinning the CPU, this
// parks the task until its wake deadline so the core can idle. Service
// capsules that poll for a dependency to come up use this instead of a tight
// yield loop, which is what used to peg the host core and starve the desktop.
pub fn sys_sleep_ms(ms: u64) -> i64 {
let Some(pid) = current_pid() else {
return ERRNO_PERM;
};
if ms == 0 {
crate::sched::yield_now();
return 0;
}
let deadline = crate::time::timestamp_millis().saturating_add(ms);
while crate::time::timestamp_millis() < deadline {
crate::sched::sleep_until(pid, deadline);
crate::sched::yield_now();
}
0
}

pub fn sys_getpid() -> i64 {
match current_pid() {
Some(pid) => pid as i64,
Expand Down
1 change: 1 addition & 0 deletions src/syscall/numbers/defs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ pub enum SyscallNumber {
MkArgs = tag4(b"MKAR"),
MkThreadSpawn = tag4(b"MTSP"),
MkYield = tag4(b"MYLD"),
MkSleepMs = tag4(b"MSLP"),
MkTimeMillis = tag4(b"MTMS"),
MkTimeRtc = tag4(b"MTRT"),
MkBatteryStatus = tag4(b"MBAT"),
Expand Down
6 changes: 5 additions & 1 deletion toolchain/nonos-std/sys/pal/nonos/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ const N_MK_EXIT: i64 = tag4(b"MEXT");
const N_MK_GETPID: i64 = tag4(b"MGPD");

pub fn getcwd() -> io::Result<PathBuf> {
unsupported()
// NONOS capsules run with a fixed root working directory. Returning "/"
// rather than an error lets unmodified crates.io tools that query the CWD
// at startup (ripgrep among them) initialize instead of bailing out with
// "failed to get current working directory".
Ok(PathBuf::from("/"))
}

pub fn chdir(_: &path::Path) -> io::Result<()> {
Expand Down
3 changes: 2 additions & 1 deletion userland/libc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub mod broker;
pub mod capsule_load;
pub mod crypto;
pub mod debug;
pub mod fuzz;
pub mod graphics;
pub mod heap;
pub mod ipc;
Expand Down Expand Up @@ -80,4 +81,4 @@ pub use surface_registry::{
};
pub use syscall::call_raw as mk_syscall_raw;
pub use time::{mk_time_millis, mk_time_rtc, RtcTime};
pub use unistd::{mk_exit, mk_yield};
pub use unistd::{mk_exit, mk_sleep_ms, mk_yield};
1 change: 1 addition & 0 deletions userland/libc/src/syscall/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub(crate) use numbers::{
N_MK_IRQ_WAIT, N_MK_MMAP, N_MK_MMIO_MAP, N_MK_MMIO_UNMAP, N_MK_PCI_CONFIG_READ,
N_MK_PCI_CONFIG_WRITE, N_MK_PID_ALIVE, N_MK_PIO_GRANT, N_MK_PIO_READ, N_MK_PIO_RELEASE,
N_MK_PIO_WRITE, N_MK_PROC_OUTPUT, N_MK_PROC_STAT, N_MK_SERVICE_LOOKUP, N_MK_SERVICE_REGISTER,
N_MK_SLEEP_MS,
N_MK_SURFACE_ATTACH, N_MK_SURFACE_PRESENT, N_MK_SURFACE_REGISTER, N_MK_SURFACE_RELEASE,
N_MK_SURFACE_SHARE, N_MK_TIME_MILLIS, N_MK_TIME_RTC, N_MK_YIELD,
};
1 change: 1 addition & 0 deletions userland/libc/src/syscall/numbers/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub(crate) const N_MK_PID_ALIVE: i64 = tag4(b"MPAL");
pub(crate) const N_MK_GETPID: i64 = tag4(b"MGPD");
pub(crate) const N_MK_ARGS: i64 = tag4(b"MKAR");
pub(crate) const N_MK_YIELD: i64 = tag4(b"MYLD");
pub(crate) const N_MK_SLEEP_MS: i64 = tag4(b"MSLP");
pub(crate) const N_MK_TIME_MILLIS: i64 = tag4(b"MTMS");
pub(crate) const N_MK_TIME_RTC: i64 = tag4(b"MTRT");
pub(crate) const N_MK_BATTERY_STATUS: i64 = tag4(b"MBAT");
Expand Down
2 changes: 1 addition & 1 deletion userland/libc/src/unistd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ mod exit;
mod sched;

pub use exit::mk_exit;
pub use sched::mk_yield;
pub use sched::{mk_sleep_ms, mk_yield};
10 changes: 9 additions & 1 deletion userland/libc/src/unistd/sched.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,17 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use crate::syscall::{call_raw, N_MK_YIELD};
use crate::syscall::{call_raw, N_MK_SLEEP_MS, N_MK_YIELD};

#[no_mangle]
pub extern "C" fn mk_yield() -> i64 {
call_raw(N_MK_YIELD, [0; 6])
}

// Park the caller for `ms` milliseconds. Use this instead of a tight
// `mk_yield` backoff loop when waiting for a dependency: yield keeps the task
// runnable and pins the CPU, this releases the core until the wake deadline.
#[no_mangle]
pub extern "C" fn mk_sleep_ms(ms: u64) -> i64 {
call_raw(N_MK_SLEEP_MS, [ms, 0, 0, 0, 0, 0])
}
Loading