diff --git a/src/syscalls/fs.rs b/src/syscalls/fs.rs index 4bcecbd5c181318c3a549c0ad440ff913b73aa00..2694bdb838e3da2b83de7f69b9ffd88627e63096 100644 --- a/src/syscalls/fs.rs +++ b/src/syscalls/fs.rs @@ -141,6 +141,9 @@ impl Filesystem { Ok(self.add_file(file)) } + /// Closes a file with given fd. + /// If the file is currently open, closes it + /// Remove the file from map of open files pub fn close(&mut self, fd: u64) { debug!("Closing fd {}", fd); if let Some(file) = self.files.get_mut(&fd) { diff --git a/src/syscalls/semaphore.rs b/src/syscalls/semaphore.rs index da23043a22f70a42e54a49262273bd87d7ffce58..29599a2571be841cc667ffe1374673db35e904d6 100644 --- a/src/syscalls/semaphore.rs +++ b/src/syscalls/semaphore.rs @@ -3,6 +3,12 @@ use alloc::boxed::Box; use crate::errno::*; use crate::synch::semaphore::Semaphore; +/// Create a new, unnamed semaphore. +/// +/// This function can be used to get the raw memory location of a semaphore. +/// +/// Stores the raw memory location of the new semaphore in parameter `sem`. +/// Returns `0` on success, `-EINVAL` if `sem` is null. extern "C" fn __sys_sem_init(sem: *mut *mut Semaphore, value: u32) -> i32 { if sem.is_null() { return -EINVAL; @@ -21,6 +27,11 @@ pub extern "C" fn sys_sem_init(sem: *mut *mut Semaphore, value: u32) -> i32 { kernel_function!(__sys_sem_init(sem, value)) } +/// Destroy and deallocate a semaphore. +/// +/// This function can be used to manually deallocate a semaphore via a reference. +/// +/// Returns `0` on success, `-EINVAL` if `sem` is null. extern "C" fn __sys_sem_destroy(sem: *mut Semaphore) -> i32 { if sem.is_null() { return -EINVAL; @@ -39,6 +50,13 @@ pub extern "C" fn sys_sem_destroy(sem: *mut Semaphore) -> i32 { kernel_function!(__sys_sem_destroy(sem)) } +/// Release a semaphore. +/// +/// This function can be used to allow the next blocked waiter to access this semaphore. +/// It will notify the next waiter that `sem` is available. +/// The semaphore is not deallocated after being released. +/// +/// Returns `0` on success, or `-EINVAL` if `sem` is null. extern "C" fn __sys_sem_post(sem: *const Semaphore) -> i32 { if sem.is_null() { return -EINVAL; @@ -55,6 +73,12 @@ pub extern "C" fn sys_sem_post(sem: *const Semaphore) -> i32 { kernel_function!(__sys_sem_post(sem)) } +/// Try to acquire a lock on a semaphore. +/// +/// This function does not block if the acquire fails. +/// If the acquire fails (i.e. the semaphore's count is already 0), the function returns immediately. +/// +/// Returns `0` on lock acquire, `-EINVAL` if `sem` is null, or `-ECANCELED` if the decrement fails. extern "C" fn __sys_sem_trywait(sem: *const Semaphore) -> i32 { if sem.is_null() { return -EINVAL; @@ -74,6 +98,11 @@ pub extern "C" fn sys_sem_trywait(sem: *const Semaphore) -> i32 { kernel_function!(__sys_sem_trywait(sem)) } +/// Try to acquire a lock on a semaphore, blocking for a given amount of milliseconds. +/// +/// Blocks until semaphore is acquired or until wake-up time has elapsed. +/// +/// Returns `0` on lock acquire, `-EINVAL` if sem is null, or `-ETIME` on timeout. extern "C" fn __sys_sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 { if sem.is_null() { return -EINVAL; diff --git a/src/syscalls/timer.rs b/src/syscalls/timer.rs index 849ed1becb129de9625e4cbde554d9ae48b26e3f..2248947e8f5bf26220ddb85006dbf8c9fd2c0fb7 100644 --- a/src/syscalls/timer.rs +++ b/src/syscalls/timer.rs @@ -46,6 +46,16 @@ pub(crate) fn timespec_to_microseconds(time: timespec) -> Option<u64> { .and_then(|millions| millions.checked_add(u64::try_from(time.tv_nsec).ok()? / 1000)) } +/// Finds the resolution (or precision) of a clock. +/// +/// This function gets the clock resolution of the clock with `clock_id` and stores it in parameter `res`. +/// Returns `0` on success, `-EINVAL` otherwise. +/// +/// Supported clocks: +/// - `CLOCK_REALTIME` +/// - `CLOCK_PROCESS_CPUTIME_ID` +/// - `CLOCK_THREAD_CPUTIME_ID` +/// - `CLOCK_MONOTONIC` extern "C" fn __sys_clock_getres(clock_id: u64, res: *mut timespec) -> i32 { assert!( !res.is_null(), @@ -71,6 +81,14 @@ pub extern "C" fn sys_clock_getres(clock_id: u64, res: *mut timespec) -> i32 { kernel_function!(__sys_clock_getres(clock_id, res)) } +/// Get the current time of a clock. +/// +/// Get the current time of the clock with `clock_id` and stores result in parameter `res`. +/// Returns `0` on success, `-EINVAL` otherwise. +/// +/// Supported clocks: +/// - `CLOCK_REALTIME` +/// - `CLOCK_MONOTONIC` extern "C" fn __sys_clock_gettime(clock_id: u64, tp: *mut timespec) -> i32 { assert!( !tp.is_null(), @@ -104,6 +122,15 @@ pub extern "C" fn sys_clock_gettime(clock_id: u64, tp: *mut timespec) -> i32 { kernel_function!(__sys_clock_gettime(clock_id, tp)) } +/// Sleep a clock for a specified number of nanoseconds. +/// +/// The requested time (in nanoseconds) must be greater than 0 and less than 1,000,000. +/// +/// Returns `0` on success, `-EINVAL` otherwise. +/// +/// Supported clocks: +/// - `CLOCK_REALTIME` +/// - `CLOCK_MONOTONIC` extern "C" fn __sys_clock_nanosleep( clock_id: u64, flags: i32, @@ -164,6 +191,12 @@ pub extern "C" fn sys_clock_settime(clock_id: u64, tp: *const timespec) -> i32 { kernel_function!(__sys_clock_settime(clock_id, tp)) } +/// Get the system's clock time. +/// +/// This function gets the current time based on the wallclock time when booted up, plus current timer ticks. +/// Returns `0` on success, `-EINVAL` otherwise. +/// +/// **Parameter `tz` should be set to `0` since tz is obsolete.** extern "C" fn __sys_gettimeofday(tp: *mut timeval, tz: usize) -> i32 { if let Some(result) = unsafe { tp.as_mut() } { // Return the current time based on the wallclock time when we were booted up