Add sys_ioprio_set and sys_ioprio_get

This commit is contained in:
Cautreoxit 2025-06-01 16:43:28 +08:00 committed by Tate, Hongliang Tian
parent 24d56cfde7
commit 6ecccad3ee
9 changed files with 133 additions and 5 deletions

View File

@ -271,8 +271,8 @@ provided by Linux on x86-64 architecture.
| 248 | add_key | ❌ |
| 249 | request_key | ❌ |
| 250 | keyctl | ❌ |
| 251 | ioprio_set | |
| 252 | ioprio_get | |
| 251 | ioprio_set | |
| 252 | ioprio_get | |
| 253 | inotify_init | ❌ |
| 254 | inotify_add_watch | ❌ |
| 255 | inotify_rm_watch | ❌ |

View File

@ -1,5 +1,7 @@
// SPDX-License-Identifier: MPL-2.0
use core::sync::atomic::AtomicU32;
use ostd::{
cpu::{
context::{FpuContext, UserContext},
@ -150,6 +152,7 @@ impl PosixThreadBuilder {
prof_clock,
virtual_timer_manager,
prof_timer_manager,
io_priority: AtomicU32::new(0),
}
};

View File

@ -76,6 +76,9 @@ pub struct PosixThread {
/// A manager that manages timers based on the profiling clock of the current thread.
prof_timer_manager: Arc<TimerManager>,
/// I/O Scheduling priority value
io_priority: AtomicU32,
}
impl PosixThread {
@ -308,6 +311,11 @@ impl PosixThread {
));
self.credentials.dup().restrict()
}
/// Returns the I/O priority value of the thread.
pub fn io_priority(&self) -> &AtomicU32 {
&self.io_priority
}
}
static POSIX_TID_ALLOCATOR: AtomicU32 = AtomicU32::new(1);

View File

@ -29,6 +29,7 @@ use super::{
flock::sys_flock,
fsync::{sys_fdatasync, sys_fsync},
futex::sys_futex,
get_ioprio::sys_ioprio_get,
get_priority::sys_get_priority,
getcpu::sys_getcpu,
getcwd::sys_getcwd,
@ -101,6 +102,7 @@ use super::{
sendfile::sys_sendfile,
sendmsg::sys_sendmsg,
sendto::sys_sendto,
set_ioprio::sys_ioprio_set,
set_priority::sys_set_priority,
set_robust_list::sys_set_robust_list,
set_tid_address::sys_set_tid_address,
@ -154,6 +156,8 @@ impl_syscall_nums_and_dispatch_fn! {
SYS_DUP3 = 24 => sys_dup3(args[..3]);
SYS_FCNTL = 25 => sys_fcntl(args[..3]);
SYS_IOCTL = 29 => sys_ioctl(args[..3]);
SYS_IOPRIO_SET = 30 => sys_ioprio_set(args[..3]);
SYS_IOPRIO_GET = 31 => sys_ioprio_get(args[..2]);
SYS_FLOCK = 32 => sys_flock(args[..2]);
SYS_MKNODAT = 33 => sys_mknodat(args[..4]);
SYS_MKDIRAT = 34 => sys_mkdirat(args[..3]);

View File

@ -35,6 +35,7 @@ use super::{
fork::{sys_fork, sys_vfork},
fsync::{sys_fdatasync, sys_fsync},
futex::sys_futex,
get_ioprio::sys_ioprio_get,
get_priority::sys_get_priority,
getcpu::sys_getcpu,
getcwd::sys_getcwd,
@ -117,6 +118,7 @@ use super::{
sendfile::sys_sendfile,
sendmsg::sys_sendmsg,
sendto::sys_sendto,
set_ioprio::sys_ioprio_set,
set_priority::sys_set_priority,
set_robust_list::sys_set_robust_list,
set_tid_address::sys_set_tid_address,
@ -335,6 +337,8 @@ impl_syscall_nums_and_dispatch_fn! {
SYS_TGKILL = 234 => sys_tgkill(args[..3]);
SYS_UTIMES = 235 => sys_utimes(args[..2]);
SYS_WAITID = 247 => sys_waitid(args[..5]);
SYS_IOPRIO_SET = 251 => sys_ioprio_set(args[..3]);
SYS_IOPRIO_GET = 252 => sys_ioprio_get(args[..2]);
SYS_OPENAT = 257 => sys_openat(args[..4]);
SYS_MKDIRAT = 258 => sys_mkdirat(args[..3]);
SYS_MKNODAT = 259 => sys_mknodat(args[..4]);

View File

@ -0,0 +1,76 @@
// SPDX-License-Identifier: MPL-2.0
use alloc::{sync::Arc, vec::Vec};
use core::sync::atomic::Ordering;
use super::SyscallReturn;
use crate::{
prelude::*,
process::{posix_thread::AsPosixThread, ProcessGroup},
thread::Thread,
};
#[expect(dead_code)]
pub(super) enum IoPrioWho {
Thread(Arc<Thread>),
ProcessGroup(Arc<ProcessGroup>),
/// The threads belong to the same user
User(Vec<Arc<Thread>>),
}
impl IoPrioWho {
const IOPRIO_WHO_PROCESS: u32 = 1;
const IOPRIO_WHO_PGRP: u32 = 2;
const IOPRIO_WHO_USER: u32 = 3;
pub(super) fn from_which_and_who(which: u32, who: u32, ctx: &Context) -> Result<Self> {
match which {
Self::IOPRIO_WHO_PROCESS => {
// In Linux, IOPRIO_WHO_PROCESS identifies a single thread by its TID
let target_tid = if who == 0 {
ctx.posix_thread.tid()
} else {
who
};
let thread = crate::process::posix_thread::thread_table::get_thread(target_tid)
.ok_or_else(|| Error::new(Errno::ESRCH))?;
Ok(Self::Thread(thread))
}
Self::IOPRIO_WHO_PGRP => {
// TODO: Implement process group support
return_errno!(Errno::EINVAL);
}
Self::IOPRIO_WHO_USER => {
// TODO: Implement user support
return_errno!(Errno::EINVAL);
}
_ => return_errno!(Errno::EINVAL),
}
}
}
pub fn sys_ioprio_get(which: u32, who: u32, ctx: &Context) -> Result<SyscallReturn> {
debug!("which = {}, who = {}", which, who);
let ioprio_who = IoPrioWho::from_which_and_who(which, who, ctx)?;
match ioprio_who {
IoPrioWho::Thread(thread) => {
let prio = thread
.as_posix_thread()
.unwrap()
.io_priority()
.load(Ordering::Relaxed);
Ok(SyscallReturn::Return(prio as _))
}
IoPrioWho::ProcessGroup(_) => {
// TODO: Implement process group support
return_errno!(Errno::EINVAL);
}
IoPrioWho::User(_) => {
// TODO: Implement user support
return_errno!(Errno::EINVAL);
}
}
}

View File

@ -44,6 +44,7 @@ mod flock;
mod fork;
mod fsync;
mod futex;
mod get_ioprio;
mod get_priority;
mod getcpu;
mod getcwd;
@ -125,6 +126,7 @@ mod semop;
mod sendfile;
mod sendmsg;
mod sendto;
mod set_ioprio;
mod set_priority;
mod set_robust_list;
mod set_tid_address;

View File

@ -0,0 +1,31 @@
// SPDX-License-Identifier: MPL-2.0
use core::sync::atomic::Ordering;
use super::{get_ioprio::IoPrioWho, SyscallReturn};
use crate::{prelude::*, process::posix_thread::AsPosixThread};
pub fn sys_ioprio_set(which: u32, who: u32, ioprio: u32, ctx: &Context) -> Result<SyscallReturn> {
debug!("which = {}, who = {}, ioprio = {}", which, who, ioprio);
let ioprio_who = IoPrioWho::from_which_and_who(which, who, ctx)?;
match ioprio_who {
IoPrioWho::Thread(thread) => {
thread
.as_posix_thread()
.unwrap()
.io_priority()
.store(ioprio, Ordering::Relaxed);
Ok(SyscallReturn::Return(0))
}
IoPrioWho::ProcessGroup(_) => {
// TODO: Implement process group support
return_errno!(Errno::EINVAL);
}
IoPrioWho::User(_) => {
// TODO: Implement user support
return_errno!(Errno::EINVAL);
}
}
}

View File

@ -651,9 +651,9 @@ getxattr01
# iopl01
# iopl02
# ioprio_get01
# ioprio_set01
# ioprio_set02
ioprio_get01
ioprio_set01
ioprio_set02
# ioprio_set03
# io_cancel01