use ax_errno::{AxError, AxResult};
use ax_task::current;
use crate::task::AsThread;
pub fn sys_getpid() -> AxResult<isize> {
Ok(current().as_thread().proc_data.proc.pid() as _)
}
pub fn sys_getppid() -> AxResult<isize> {
current()
.as_thread()
.proc_data
.proc
.parent()
.ok_or(AxError::NoSuchProcess)
.map(|p| p.pid() as _)
}
pub fn sys_gettid() -> AxResult<isize> {
Ok(current().as_thread().tid() as _)
}
#[cfg(target_arch = "x86_64")]
#[derive(Debug, Eq, PartialEq, num_enum::TryFromPrimitive)]
#[repr(i32)]
enum ArchPrctlCode {
SetGs = 0x1001,
SetFs = 0x1002,
GetFs = 0x1003,
GetGs = 0x1004,
GetCpuid = 0x1011,
SetCpuid = 0x1012,
}
pub fn sys_set_tid_address(clear_child_tid: usize) -> AxResult<isize> {
let curr = current();
let thr = curr.as_thread();
thr.set_clear_child_tid(clear_child_tid);
Ok(thr.tid() as isize)
}
#[cfg(target_arch = "x86_64")]
pub fn sys_arch_prctl(
uctx: &mut ax_hal::uspace::UserContext,
code: i32,
addr: usize,
) -> AxResult<isize> {
use starry_vm::VmMutPtr;
let code = ArchPrctlCode::try_from(code).map_err(|_| AxError::InvalidInput)?;
debug!("sys_arch_prctl: code = {code:?}, addr = {addr:#x}");
match code {
ArchPrctlCode::GetFs => {
(addr as *mut usize).vm_write(uctx.tls())?;
Ok(0)
}
ArchPrctlCode::SetFs => {
uctx.set_tls(addr);
Ok(0)
}
ArchPrctlCode::GetGs => {
(addr as *mut usize).vm_write(uctx.gs_base as _)?;
Ok(0)
}
ArchPrctlCode::SetGs => {
uctx.gs_base = addr as _;
Ok(0)
}
ArchPrctlCode::GetCpuid => Ok(0),
ArchPrctlCode::SetCpuid => Err(ax_errno::AxError::NoSuchDevice),
}
}