Skip to content

Commit

Permalink
Merge pull request #1167 from stlankes/stabelized
Browse files Browse the repository at this point in the history
feat: stabilize kernel interface
  • Loading branch information
mkroening authored May 6, 2024
2 parents 87ebdd3 + 0e17161 commit 25fb095
Show file tree
Hide file tree
Showing 9 changed files with 168 additions and 78 deletions.
7 changes: 7 additions & 0 deletions src/errno.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,13 @@ pub(crate) static ERRNO: core::cell::UnsafeCell<i32> = core::cell::UnsafeCell::n
#[cfg(not(feature = "nostd"))]
#[no_mangle]
pub extern "C" fn sys_get_errno() -> i32 {
sys_errno()
}

/// Get the error number from the thread local storage
#[cfg(not(feature = "nostd"))]
#[no_mangle]
pub extern "C" fn sys_errno() -> i32 {
cfg_if::cfg_if! {
if #[cfg(any(feature = "common-os", target_arch = "riscv64"))] {
0
Expand Down
4 changes: 2 additions & 2 deletions src/scheduler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use alloc::vec::Vec;
use core::cell::RefCell;
use core::future::{self, Future};
use core::ptr;
use core::sync::atomic::{AtomicU32, Ordering};
use core::sync::atomic::{AtomicI32, AtomicU32, Ordering};
use core::task::ready;
use core::task::Poll::Ready;

Expand Down Expand Up @@ -873,7 +873,7 @@ impl PerCoreScheduler {
}

fn get_tid() -> TaskId {
static TID_COUNTER: AtomicU32 = AtomicU32::new(0);
static TID_COUNTER: AtomicI32 = AtomicI32::new(0);
let guard = TASKS.lock();

loop {
Expand Down
6 changes: 3 additions & 3 deletions src/scheduler/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ pub(crate) enum TaskStatus {

/// Unique identifier for a task (i.e. `pid`).
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
pub struct TaskId(u32);
pub struct TaskId(i32);

impl TaskId {
pub const fn into(self) -> u32 {
pub const fn into(self) -> i32 {
self.0
}

pub const fn from(x: u32) -> Self {
pub const fn from(x: i32) -> Self {
TaskId(x)
}
}
Expand Down
84 changes: 78 additions & 6 deletions src/syscalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#[cfg(all(target_os = "none", not(feature = "common-os")))]
use core::alloc::{GlobalAlloc, Layout};
use core::ffi::CStr;
use core::ffi::{c_char, CStr};
use core::marker::PhantomData;

#[cfg(feature = "newlib")]
Expand Down Expand Up @@ -80,6 +80,54 @@ pub(crate) fn init() {
/// Returning a null pointer indicates that either memory is exhausted or
/// `size` and `align` do not meet this allocator's size or alignment constraints.
///
#[cfg(all(target_os = "none", not(feature = "common-os")))]
#[hermit_macro::system]
pub extern "C" fn sys_alloc(size: usize, align: usize) -> *mut u8 {
let layout_res = Layout::from_size_align(size, align);
if layout_res.is_err() || size == 0 {
warn!(
"__sys_alloc called with size {:#x}, align {:#x} is an invalid layout!",
size, align
);
return core::ptr::null_mut();
}
let layout = layout_res.unwrap();
let ptr = unsafe { ALLOCATOR.alloc(layout) };

trace!(
"__sys_alloc: allocate memory at {:p} (size {:#x}, align {:#x})",
ptr,
size,
align
);

ptr
}

#[cfg(all(target_os = "none", not(feature = "common-os")))]
#[hermit_macro::system]
pub extern "C" fn sys_alloc_zeroed(size: usize, align: usize) -> *mut u8 {
let layout_res = Layout::from_size_align(size, align);
if layout_res.is_err() || size == 0 {
warn!(
"__sys_alloc_zeroed called with size {:#x}, align {:#x} is an invalid layout!",
size, align
);
return core::ptr::null_mut();
}
let layout = layout_res.unwrap();
let ptr = unsafe { ALLOCATOR.alloc_zeroed(layout) };

trace!(
"__sys_alloc_zeroed: allocate memory at {:p} (size {:#x}, align {:#x})",
ptr,
size,
align
);

ptr
}

#[cfg(all(target_os = "none", not(feature = "common-os")))]
#[hermit_macro::system]
pub extern "C" fn sys_malloc(size: usize, align: usize) -> *mut u8 {
Expand Down Expand Up @@ -169,6 +217,30 @@ pub unsafe extern "C" fn sys_realloc(
///
/// # Errors
/// May panic if debug assertions are enabled and invalid parameters `size` or `align` where passed.
#[cfg(all(target_os = "none", not(feature = "common-os")))]
#[hermit_macro::system]
pub unsafe extern "C" fn sys_dealloc(ptr: *mut u8, size: usize, align: usize) {
unsafe {
let layout_res = Layout::from_size_align(size, align);
if layout_res.is_err() || size == 0 {
warn!(
"__sys_dealloc called with size {:#x}, align {:#x} is an invalid layout!",
size, align
);
debug_assert!(layout_res.is_err(), "__sys_dealloc error: Invalid layout");
debug_assert_ne!(size, 0, "__sys_dealloc error: size cannot be 0");
} else {
trace!(
"sys_free: deallocate memory at {:p} (size {:#x})",
ptr,
size
);
}
let layout = layout_res.unwrap();
ALLOCATOR.dealloc(ptr, layout);
}
}

#[cfg(all(target_os = "none", not(feature = "common-os")))]
#[hermit_macro::system]
pub unsafe extern "C" fn sys_free(ptr: *mut u8, size: usize, align: usize) {
Expand Down Expand Up @@ -238,7 +310,7 @@ pub unsafe extern "C" fn sys_mkdir(name: *const u8, mode: u32) -> i32 {
}

#[hermit_macro::system]
pub unsafe extern "C" fn sys_rmdir(name: *const u8) -> i32 {
pub unsafe extern "C" fn sys_rmdir(name: *const c_char) -> i32 {
let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap();

fs::FILESYSTEM
Expand All @@ -249,7 +321,7 @@ pub unsafe extern "C" fn sys_rmdir(name: *const u8) -> i32 {
}

#[hermit_macro::system]
pub unsafe extern "C" fn sys_stat(name: *const u8, stat: *mut FileAttr) -> i32 {
pub unsafe extern "C" fn sys_stat(name: *const c_char, stat: *mut FileAttr) -> i32 {
let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap();

match fs::FILESYSTEM.get().unwrap().stat(name) {
Expand All @@ -262,7 +334,7 @@ pub unsafe extern "C" fn sys_stat(name: *const u8, stat: *mut FileAttr) -> i32 {
}

#[hermit_macro::system]
pub unsafe extern "C" fn sys_lstat(name: *const u8, stat: *mut FileAttr) -> i32 {
pub unsafe extern "C" fn sys_lstat(name: *const c_char, stat: *mut FileAttr) -> i32 {
let name = unsafe { CStr::from_ptr(name as _) }.to_str().unwrap();

match fs::FILESYSTEM.get().unwrap().lstat(name) {
Expand All @@ -288,7 +360,7 @@ pub unsafe extern "C" fn sys_fstat(fd: FileDescriptor, stat: *mut FileAttr) -> i
}

#[hermit_macro::system]
pub unsafe extern "C" fn sys_opendir(name: *const u8) -> FileDescriptor {
pub unsafe extern "C" fn sys_opendir(name: *const c_char) -> FileDescriptor {
if let Ok(name) = unsafe { CStr::from_ptr(name as _) }.to_str() {
crate::fs::opendir(name).unwrap_or_else(|e| -num::ToPrimitive::to_i32(&e).unwrap())
} else {
Expand All @@ -297,7 +369,7 @@ pub unsafe extern "C" fn sys_opendir(name: *const u8) -> FileDescriptor {
}

#[hermit_macro::system]
pub unsafe extern "C" fn sys_open(name: *const u8, flags: i32, mode: u32) -> FileDescriptor {
pub unsafe extern "C" fn sys_open(name: *const c_char, flags: i32, mode: u32) -> FileDescriptor {
let flags = if let Some(flags) = OpenOption::from_bits(flags) {
flags
} else {
Expand Down
51 changes: 34 additions & 17 deletions src/syscalls/semaphore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ use alloc::boxed::Box;

use crate::errno::*;
use crate::synch::semaphore::Semaphore;
use crate::time::timespec;

#[allow(non_camel_case_types)]
pub type sem_t = *const Semaphore;

/// Create a new, unnamed semaphore.
///
Expand All @@ -10,8 +14,8 @@ use crate::synch::semaphore::Semaphore;
/// Stores the raw memory location of the new semaphore in parameter `sem`.
/// Returns `0` on success, `-EINVAL` if `sem` is null.
#[hermit_macro::system]
pub unsafe extern "C" fn sys_sem_init(sem: *mut *mut Semaphore, value: u32) -> i32 {
if sem.is_null() {
pub unsafe extern "C" fn sys_sem_init(sem: *mut sem_t, pshared: i32, value: u32) -> i32 {
if sem.is_null() || pshared != 0 {
return -EINVAL;
}

Expand All @@ -29,7 +33,7 @@ pub unsafe extern "C" fn sys_sem_init(sem: *mut *mut Semaphore, value: u32) -> i
///
/// Returns `0` on success, `-EINVAL` if `sem` is null.
#[hermit_macro::system]
pub unsafe extern "C" fn sys_sem_destroy(sem: *mut Semaphore) -> i32 {
pub unsafe extern "C" fn sys_sem_destroy(sem: *mut sem_t) -> i32 {
if sem.is_null() {
return -EINVAL;
}
Expand All @@ -50,13 +54,13 @@ pub unsafe extern "C" fn sys_sem_destroy(sem: *mut Semaphore) -> i32 {
///
/// Returns `0` on success, or `-EINVAL` if `sem` is null.
#[hermit_macro::system]
pub unsafe extern "C" fn sys_sem_post(sem: *const Semaphore) -> i32 {
pub unsafe extern "C" fn sys_sem_post(sem: *mut sem_t) -> i32 {
if sem.is_null() {
return -EINVAL;
}

// Get a reference to the given semaphore and release it.
let semaphore = unsafe { &*sem };
let semaphore = unsafe { &**sem };
semaphore.release();
0
}
Expand All @@ -68,47 +72,60 @@ pub unsafe extern "C" fn sys_sem_post(sem: *const Semaphore) -> i32 {
///
/// Returns `0` on lock acquire, `-EINVAL` if `sem` is null, or `-ECANCELED` if the decrement fails.
#[hermit_macro::system]
pub unsafe extern "C" fn sys_sem_trywait(sem: *const Semaphore) -> i32 {
pub unsafe extern "C" fn sys_sem_trywait(sem: *mut sem_t) -> i32 {
if sem.is_null() {
return -EINVAL;
}

// Get a reference to the given semaphore and acquire it in a non-blocking fashion.
let semaphore = unsafe { &*sem };
let semaphore = unsafe { &**sem };
if semaphore.try_acquire() {
0
} else {
-ECANCELED
}
}

unsafe fn sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 {
unsafe fn sem_timedwait(sem: *mut sem_t, ms: u32) -> i32 {
if sem.is_null() {
return -EINVAL;
}

let delay = if ms > 0 { Some(u64::from(ms)) } else { None };

// Get a reference to the given semaphore and wait until we have acquired it or the wakeup time has elapsed.
let semaphore = unsafe { &*sem };
let semaphore = unsafe { &**sem };
if semaphore.acquire(delay) {
0
} else {
-ETIME
}
}

/// Try to acquire a lock on a semaphore, blocking for a given amount of milliseconds.
/// Try to acquire a lock on a semaphore.
///
/// Blocks until semaphore is acquired or until wake-up time has elapsed.
/// Blocks until semaphore is acquired or until specified time passed
///
/// Returns `0` on lock acquire, `-EINVAL` if sem is null, or `-ETIME` on timeout.
#[hermit_macro::system]
pub unsafe extern "C" fn sys_sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 {
unsafe { sem_timedwait(sem, ms) }
}
pub unsafe extern "C" fn sys_sem_timedwait(sem: *mut sem_t, ts: *const timespec) -> i32 {
if ts.is_null() {
unsafe { sem_timedwait(sem, 0) }
} else {
let mut current_ts: timespec = Default::default();

#[hermit_macro::system]
pub unsafe extern "C" fn sys_sem_cancelablewait(sem: *const Semaphore, ms: u32) -> i32 {
unsafe { sem_timedwait(sem, ms) }
unsafe {
crate::sys_clock_gettime(crate::CLOCK_REALTIME, &mut current_ts as *mut _);

let ts = &*ts;
let ms: i64 = (ts.tv_sec - current_ts.tv_sec) * 1000
+ (ts.tv_nsec as i64 - current_ts.tv_nsec as i64) / 1000000;

if ms > 0 {
sem_timedwait(sem, ms.try_into().unwrap())
} else {
0
}
}
}
}
Loading

0 comments on commit 25fb095

Please sign in to comment.