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
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ ringbuf = { version = "0.4.8", default-features = false, features = ["alloc"] }
bitflags = "2.9.1"
futures = { version = "0.3.31", default-features = false, features = ["alloc", "async-await"] }
rand = { version = "0.9.2", default-features = false, features = ["small_rng"] }
rustc-hash = { version = "2.1", default-features = false }

[features]
default = ["smp"]
Expand Down
75 changes: 75 additions & 0 deletions libkernel/src/fs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,3 +322,78 @@ pub trait Inode: Send + Sync + Any {
Ok(())
}
}

/// A simplified trait for read-only files in procfs/sysfs that provides default implementations
/// for common inode operations.
#[async_trait]
pub trait SimpleFile {
fn id(&self) -> InodeId;
async fn getattr(&self) -> Result<FileAttr>;
async fn read(&self) -> Result<Vec<u8>>;
async fn readlink(&self) -> Result<PathBuf> {
Err(KernelError::NotSupported)
}
}

#[async_trait]
impl<T> Inode for T
where
T: SimpleFile + Send + Sync + 'static,
{
fn id(&self) -> InodeId {
self.id()
}

async fn read_at(&self, offset: u64, buf: &mut [u8]) -> Result<usize> {
let bytes = self.read().await?;
let end = usize::min(bytes.len().saturating_sub(offset as usize), buf.len());
if end == 0 {
return Ok(0);
}
let slice = &bytes[offset as usize..offset as usize + end];
buf[..end].copy_from_slice(slice);
Ok(end)
}

async fn getattr(&self) -> Result<FileAttr> {
self.getattr().await
}

async fn lookup(&self, _name: &str) -> Result<Arc<dyn Inode>> {
Err(FsError::NotADirectory.into())
}

async fn readdir(&self, _start_offset: u64) -> crate::error::Result<Box<dyn DirStream>> {
Err(FsError::NotADirectory.into())
}

async fn readlink(&self) -> Result<PathBuf> {
self.readlink().await
}
}

pub struct SimpleDirStream {
entries: Vec<Dirent>,
idx: usize,
}

impl SimpleDirStream {
pub fn new(entries: Vec<Dirent>, start_offset: u64) -> Self {
Self {
entries,
idx: start_offset as usize,
}
}
}

#[async_trait]
impl DirStream for SimpleDirStream {
async fn next_entry(&mut self) -> Result<Option<Dirent>> {
Ok(if let Some(entry) = self.entries.get(self.idx).cloned() {
self.idx += 1;
Some(entry)
} else {
None
})
}
}
4 changes: 4 additions & 0 deletions src/arch/arm64/exceptions/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ use libkernel::{
};

pub async fn handle_syscall() {
current_task().update_accounting(None);
current_task().in_syscall = true;
ptrace_stop(TracePoint::SyscallEntry).await;

let (nr, arg1, arg2, arg3, arg4, arg5, arg6) = {
Expand Down Expand Up @@ -614,4 +616,6 @@ pub async fn handle_syscall() {

current_task().ctx.user_mut().x[0] = ret_val.cast_unsigned() as u64;
ptrace_stop(TracePoint::SyscallExit).await;
current_task().update_accounting(None);
current_task().in_syscall = false;
}
41 changes: 30 additions & 11 deletions src/clock/gettime.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,40 @@
use core::sync::atomic::Ordering;
use core::time::Duration;
use libkernel::{
error::{KernelError, Result},
memory::address::TUA,
};

use super::{ClockId, realtime::date, timespec::TimeSpec};
use crate::drivers::timer::{Instant, now};
use crate::sched::current::current_task_shared;
use crate::{drivers::timer::uptime, memory::uaccess::copy_to_user};

use super::{realtime::date, timespec::TimeSpec};

pub type ClockId = i32;

const CLOCK_MONOTONIC: ClockId = 0;
const CLOCK_REALTIME: ClockId = 1;

pub async fn sys_clock_gettime(clockid: ClockId, time_spec: TUA<TimeSpec>) -> Result<usize> {
let time = match clockid {
CLOCK_MONOTONIC => uptime(),
CLOCK_REALTIME => date(),
pub async fn sys_clock_gettime(clockid: i32, time_spec: TUA<TimeSpec>) -> Result<usize> {
let time = match ClockId::try_from(clockid).map_err(|_| KernelError::InvalidValue)? {
ClockId::Monotonic => uptime(),
ClockId::Realtime => date(),
ClockId::ProcessCpuTimeId => {
let task = current_task_shared();
let total_time = task.process.stime.load(Ordering::Relaxed) as u64
+ task.process.utime.load(Ordering::Relaxed) as u64;
let last_update = Instant::from_user_normalized(
task.process.last_account.load(Ordering::Relaxed) as u64,
);
let now = now().unwrap();
let delta = now - last_update;
Duration::from(Instant::from_user_normalized(total_time)) + delta
}
ClockId::ThreadCpuTimeId => {
let task = current_task_shared();
let total_time = task.stime.load(Ordering::Relaxed) as u64
+ task.utime.load(Ordering::Relaxed) as u64;
let last_update =
Instant::from_user_normalized(task.last_account.load(Ordering::Relaxed) as u64);
let now = now().unwrap();
let delta = now - last_update;
Duration::from(Instant::from_user_normalized(total_time)) + delta
}
_ => return Err(KernelError::InvalidValue),
};

Expand Down
35 changes: 35 additions & 0 deletions src/clock/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,38 @@ pub mod gettime;
pub mod realtime;
pub mod timeofday;
pub mod timespec;

pub enum ClockId {
Monotonic = 0,
Realtime = 1,
ProcessCpuTimeId = 2,
ThreadCpuTimeId = 3,
MonotonicRaw = 4,
RealtimeCoarse = 5,
MonotonicCoarse = 6,
BootTime = 7,
RealtimeAlarm = 8,
BootTimeAlarm = 9,
Tai = 11,
}

impl TryFrom<i32> for ClockId {
type Error = ();

fn try_from(value: i32) -> Result<Self, Self::Error> {
match value {
0 => Ok(ClockId::Monotonic),
1 => Ok(ClockId::Realtime),
2 => Ok(ClockId::ProcessCpuTimeId),
3 => Ok(ClockId::ThreadCpuTimeId),
4 => Ok(ClockId::MonotonicRaw),
5 => Ok(ClockId::RealtimeCoarse),
6 => Ok(ClockId::MonotonicCoarse),
7 => Ok(ClockId::BootTime),
8 => Ok(ClockId::RealtimeAlarm),
9 => Ok(ClockId::BootTimeAlarm),
11 => Ok(ClockId::Tai),
_ => Err(()),
}
}
}
Loading
Loading