refactor: replace u32 with Tid type

This commit is contained in:
Mark Poliakov 2021-11-30 18:35:10 +02:00
parent e965c25181
commit d0681eb589
12 changed files with 108 additions and 77 deletions

View File

@ -150,7 +150,7 @@ extern "C" fn __aa64_exc_sync_handler(exc: &mut ExceptionFrame) {
if sched::is_ready() {
let thread = Thread::current();
errorln!(
"Unhandled exception in thread {}, {:?}",
"Unhandled exception in thread {:?}, {:?}",
thread.id(),
thread.owner().map(|e| e.id())
);

View File

@ -3,7 +3,7 @@
use crate::init;
use crate::sync::IrqSafeSpinLock;
use alloc::collections::BTreeMap;
use libsys::proc::Pid;
use libsys::proc::{Tid, Pid};
pub mod elf;
pub mod thread;
@ -30,7 +30,7 @@ pub fn switch() {
pub(self) static PROCESSES: IrqSafeSpinLock<BTreeMap<Pid, ProcessRef>> =
IrqSafeSpinLock::new(BTreeMap::new());
pub(self) static THREADS: IrqSafeSpinLock<BTreeMap<u32, ThreadRef>> =
pub(self) static THREADS: IrqSafeSpinLock<BTreeMap<Tid, ThreadRef>> =
IrqSafeSpinLock::new(BTreeMap::new());
/// Sets up initial process and enters it.

View File

@ -6,7 +6,7 @@ use crate::mem::{
virt::{MapAttributes, Space},
};
use crate::proc::{
wait::Wait, Context, ProcessIo, Thread, ThreadRef, ThreadState, PROCESSES, SCHED,
wait::Wait, Context, ProcessIo, Thread, ThreadRef, ThreadState, PROCESSES, SCHED, Tid,
};
use crate::sync::IrqSafeSpinLock;
use alloc::{rc::Rc, vec::Vec};
@ -39,7 +39,7 @@ struct ProcessInner {
ppid: Option<Pid>,
sid: Pid,
exit: Option<ExitCode>,
threads: Vec<u32>,
threads: Vec<Tid>,
}
/// Structure describing an operating system process
@ -184,7 +184,7 @@ impl Process {
}
/// Crates a new thread in the process
pub fn new_user_thread(&self, entry: usize, stack: usize, arg: usize) -> Result<u32, Errno> {
pub fn new_user_thread(&self, entry: usize, stack: usize, arg: usize) -> Result<Tid, Errno> {
let mut lock = self.inner.lock();
let space_phys = lock.space.as_mut().unwrap().address_phys();
@ -294,7 +294,7 @@ impl Process {
thread.terminate(status);
SCHED.dequeue(tid);
debugln!("Thread {} terminated", tid);
debugln!("Thread {:?} terminated", tid);
switch
};

View File

@ -2,12 +2,13 @@
use crate::proc::{Thread, ThreadRef, THREADS};
use crate::sync::IrqSafeSpinLock;
use crate::util::InitOnce;
use libsys::proc::Tid;
use alloc::{collections::VecDeque, rc::Rc};
struct SchedulerInner {
queue: VecDeque<u32>,
idle: Option<u32>,
current: Option<u32>,
queue: VecDeque<Tid>,
idle: Option<Tid>,
current: Option<Tid>,
}
/// Process scheduler state and queues
@ -23,7 +24,9 @@ impl SchedulerInner {
current: None,
};
this.idle = Some(Thread::new_kernel(None, idle_fn, 0).unwrap().id());
let idle = Thread::new_kernel(None, idle_fn, 0).unwrap().id();
assert_eq!(idle, Tid::IDLE);
this.idle = Some(idle);
this
}
@ -39,12 +42,12 @@ impl Scheduler {
}
/// Schedules a thread for execution
pub fn enqueue(&self, tid: u32) {
pub fn enqueue(&self, tid: Tid) {
self.inner.get().lock().queue.push_back(tid);
}
/// Removes given `tid` from execution queue
pub fn dequeue(&self, tid: u32) {
pub fn dequeue(&self, tid: Tid) {
self.inner.get().lock().queue.retain(|&p| p != tid)
}
@ -76,7 +79,7 @@ impl Scheduler {
/// # Safety
///
/// Unsafe: only allowed to be called from Process::execve()
pub unsafe fn hack_current_tid(&self, old: u32, new: u32) {
pub unsafe fn hack_current_tid(&self, old: Tid, new: Tid) {
let mut lock = self.inner.get().lock();
match lock.current {
Some(t) if t == old => {
@ -93,7 +96,7 @@ impl Scheduler {
let mut inner = self.inner.get().lock();
let current = inner.current.unwrap();
if !discard && current != 0 {
if !discard && current != Tid::IDLE {
// Put the process into the back of the queue
inner.queue.push_back(current);
}

View File

@ -12,7 +12,7 @@ use core::cell::UnsafeCell;
use core::sync::atomic::{AtomicU32, Ordering};
use libsys::{
error::Errno,
proc::{ExitCode, Pid},
proc::{ExitCode, Pid, Tid},
signal::Signal,
};
@ -35,7 +35,7 @@ pub enum State {
}
struct ThreadInner {
id: u32,
id: Tid,
state: State,
owner: Option<Pid>,
pending_wait: Option<&'static Wait>,
@ -63,7 +63,7 @@ impl Thread {
/// Returns a reference to thread `tid`, if it exists
#[inline]
pub fn get(tid: u32) -> Option<ThreadRef> {
pub fn get(tid: Tid) -> Option<ThreadRef> {
THREADS.lock().get(&tid).cloned()
}
@ -169,7 +169,7 @@ impl Thread {
/// Returns the thread ID
#[inline]
pub fn id(&self) -> u32 {
pub fn id(&self) -> Tid {
self.inner.lock().id
}
@ -244,7 +244,7 @@ impl Thread {
}
/// Suspends current thread until thread `tid` terminates
pub fn waittid(tid: u32) -> Result<(), Errno> {
pub fn waittid(tid: Tid) -> Result<(), Errno> {
loop {
let thread = THREADS
.lock()
@ -334,7 +334,7 @@ impl Thread {
let signal_ctx = unsafe { &mut *self.signal_ctx.get() };
debugln!(
"Signal entry: tid={}, pc={:#x}, sp={:#x}, ttbr0={:#x}",
"Signal entry: tid={:?}, pc={:#x}, sp={:#x}, ttbr0={:#x}",
lock.id,
lock.signal_entry,
lock.signal_stack,
@ -398,9 +398,8 @@ impl Drop for Thread {
}
/// Allocates a new thread ID
pub fn new_tid() -> u32 {
static LAST: AtomicU32 = AtomicU32::new(1);
pub fn new_tid() -> Tid {
static LAST: AtomicU32 = AtomicU32::new(0);
let id = LAST.fetch_add(1, Ordering::Relaxed);
assert!(id < 256, "Out of user TIDs");
id
Tid::from(id)
}

View File

@ -6,12 +6,12 @@ use crate::proc::{sched::SCHED, Thread, ThreadRef};
use crate::sync::IrqSafeSpinLock;
use alloc::collections::LinkedList;
use core::time::Duration;
use libsys::{error::Errno, stat::FdSet};
use libsys::{error::Errno, proc::Tid, stat::FdSet};
/// Wait channel structure. Contains a queue of processes
/// waiting for some event to happen.
pub struct Wait {
queue: IrqSafeSpinLock<LinkedList<u32>>,
queue: IrqSafeSpinLock<LinkedList<Tid>>,
#[allow(dead_code)]
name: &'static str
}
@ -28,7 +28,7 @@ pub enum WaitStatus {
}
struct Timeout {
tid: u32,
tid: Tid,
deadline: Duration,
}
@ -129,7 +129,7 @@ impl Wait {
}
/// Interrupt wait pending on the channel
pub fn abort(&self, tid: u32, enqueue: bool) {
pub fn abort(&self, tid: Tid, enqueue: bool) {
let mut queue = self.queue.lock();
let mut tick_lock = TICK_LIST.lock();
let mut cursor = tick_lock.cursor_front_mut();

View File

@ -1,10 +1,10 @@
//! System call implementation
use crate::arch::{machine, platform::exception::ExceptionFrame};
use crate::mem::{virt::MapAttributes, phys::PageUsage};
use crate::debug::Level;
use crate::dev::timer::TimestampSource;
use crate::fs::create_filesystem;
use crate::mem::{phys::PageUsage, virt::MapAttributes};
use crate::proc::{self, elf, wait, Process, ProcessIo, Thread};
use core::mem::size_of;
use core::ops::DerefMut;
@ -14,7 +14,7 @@ use libsys::{
debug::TraceLevel,
error::Errno,
ioctl::IoctlCmd,
proc::{ExitCode, Pid, MemoryAccess},
proc::{ExitCode, MemoryAccess, Pid, Tid},
signal::{Signal, SignalDestination},
stat::{
AccessMode, DirectoryEntry, FdSet, FileDescriptor, FileMode, GroupId, MountOptions,
@ -210,7 +210,8 @@ pub fn syscall(num: SystemCall, args: &[usize]) -> Result<usize, Errno> {
let acc = MemoryAccess::from_bits(args[2] as u32).ok_or(Errno::InvalidArgument)?;
let _flags = MemoryAccess::from_bits(args[3] as u32).ok_or(Errno::InvalidArgument)?;
let mut attrs = MapAttributes::NOT_GLOBAL | MapAttributes::SH_OUTER | MapAttributes::PXN;
let mut attrs =
MapAttributes::NOT_GLOBAL | MapAttributes::SH_OUTER | MapAttributes::PXN;
if !acc.contains(MemoryAccess::READ) {
return Err(Errno::NotImplemented);
}
@ -244,9 +245,7 @@ pub fn syscall(num: SystemCall, args: &[usize]) -> Result<usize, Errno> {
}
let proc = Process::current();
proc.manipulate_space(move |space| {
space.free(addr, len / 4096)
})?;
proc.manipulate_space(move |space| space.free(addr, len / 4096))?;
Ok(0)
}
@ -258,7 +257,7 @@ pub fn syscall(num: SystemCall, args: &[usize]) -> Result<usize, Errno> {
Process::current()
.new_user_thread(entry, stack, arg)
.map(|e| e as usize)
.map(|e| u32::from(e) as usize)
}
SystemCall::Exec => {
let filename = arg::str_ref(args[0], args[1])?;
@ -305,7 +304,7 @@ pub fn syscall(num: SystemCall, args: &[usize]) -> Result<usize, Errno> {
}
}
SystemCall::WaitTid => {
let tid = args[0] as u32;
let tid = Tid::from(args[0] as u32);
match Thread::waittid(tid) {
Ok(_) => Ok(0),
@ -313,7 +312,7 @@ pub fn syscall(num: SystemCall, args: &[usize]) -> Result<usize, Errno> {
}
}
SystemCall::GetPid => Ok(u32::from(Process::current().id()) as usize),
SystemCall::GetTid => Ok(Thread::current().id() as usize),
SystemCall::GetTid => Ok(u32::from(Thread::current().id()) as usize),
SystemCall::Sleep => {
let rem_buf = arg::option_buf_ref(args[1], size_of::<u64>() * 2)?;
let mut rem = Duration::new(0, 0);
@ -353,30 +352,28 @@ pub fn syscall(num: SystemCall, args: &[usize]) -> Result<usize, Errno> {
}
SystemCall::GetSid => {
// TODO handle kernel processes here?
let pid = args[0] as u32;
let pid = Pid::to_option(args[0] as u32);
let current = Process::current();
let proc = if pid == 0 {
current
} else {
let pid = Pid::try_from(pid)?;
let proc = if let Some(pid) = pid {
let proc = Process::get(pid).ok_or(Errno::DoesNotExist)?;
if proc.sid() != current.sid() {
return Err(Errno::PermissionDenied);
}
proc
} else {
current
};
Ok(u32::from(proc.sid()) as usize)
}
SystemCall::GetPgid => {
// TODO handle kernel processes here?
let pid = args[0] as u32;
let pid = Pid::to_option(args[0] as u32);
let current = Process::current();
let proc = if pid == 0 {
current
} else {
let pid = Pid::try_from(pid)?;
let proc = if let Some(pid) = pid {
Process::get(pid).ok_or(Errno::DoesNotExist)?
} else {
current
};
Ok(u32::from(proc.pgid()) as usize)
@ -395,16 +392,20 @@ pub fn syscall(num: SystemCall, args: &[usize]) -> Result<usize, Errno> {
Ok(u32::from(id) as usize)
}
SystemCall::SetPgid => {
let pid = args[0] as u32;
let pgid = args[1] as u32;
let pid = Pid::to_option(args[0] as u32);
let pgid = Pid::to_option(args[1] as u32);
let current = Process::current();
let proc = if pid == 0 { current } else { todo!() };
if pgid == 0 {
proc.set_pgid(proc.id());
let proc = if let Some(_pid) = pid {
todo!()
} else {
current
};
if let Some(_pgid) = pgid {
todo!();
} else {
proc.set_pgid(proc.id());
}
Ok(u32::from(proc.pgid()) as usize)
@ -440,7 +441,7 @@ pub fn syscall(num: SystemCall, args: &[usize]) -> Result<usize, Errno> {
let buf = arg::str_ref(args[1], args[2])?;
let thread = Thread::current();
let proc = thread.owner().unwrap();
println!(level, "[trace {:?}:{}] {}", proc.id(), thread.id(), buf);
println!(level, "[trace {:?}:{:?}] {}", proc.id(), thread.id(), buf);
Ok(args[1])
}

View File

@ -3,7 +3,7 @@ use crate::{
debug::TraceLevel,
error::Errno,
ioctl::IoctlCmd,
proc::{ExitCode, MemoryAccess, MemoryMap, Pid},
proc::{ExitCode, MemoryAccess, MemoryMap, Pid, Tid},
signal::{Signal, SignalDestination},
stat::{
AccessMode, DirectoryEntry, FdSet, FileDescriptor, FileMode, GroupId, MountOptions,
@ -289,10 +289,10 @@ pub fn sys_ex_kill(pid: SignalDestination, signum: Signal) -> Result<(), Errno>
}
#[inline(always)]
pub fn sys_ex_clone(entry: usize, stack: usize, arg: usize) -> Result<usize, Errno> {
pub fn sys_ex_clone(entry: usize, stack: usize, arg: usize) -> Result<Tid, Errno> {
Errno::from_syscall(unsafe {
syscall!(SystemCall::Clone, argn!(entry), argn!(stack), argn!(arg))
})
}).map(|e| Tid::from(e as u32))
}
#[inline(always)]
@ -304,8 +304,8 @@ pub fn sys_ex_thread_exit(status: ExitCode) -> ! {
}
#[inline(always)]
pub fn sys_ex_thread_wait(tid: u32) -> Result<ExitCode, Errno> {
Errno::from_syscall(unsafe { syscall!(SystemCall::WaitTid, argn!(tid)) })
pub fn sys_ex_thread_wait(tid: Tid) -> Result<ExitCode, Errno> {
Errno::from_syscall(unsafe { syscall!(SystemCall::WaitTid, argn!(u32::from(tid))) })
.map(|_| ExitCode::from(0))
}
@ -356,8 +356,8 @@ pub fn sys_faccessat(
}
#[inline(always)]
pub fn sys_ex_gettid() -> u32 {
unsafe { syscall!(SystemCall::GetTid) as u32 }
pub fn sys_ex_gettid() -> Tid {
Tid::from(unsafe { syscall!(SystemCall::GetTid) as u32 })
}
#[inline(always)]
@ -374,7 +374,11 @@ pub fn sys_getpgid(pid: Option<Pid>) -> Result<Pid, Errno> {
#[inline(always)]
pub fn sys_setpgid(pid: Option<Pid>, pgid: Option<Pid>) -> Result<Pid, Errno> {
Errno::from_syscall(unsafe {
syscall!(SystemCall::SetPgid, argn!(Pid::from_option(pid)), argn!(Pid::from_option(pgid)))
syscall!(
SystemCall::SetPgid,
argn!(Pid::from_option(pid)),
argn!(Pid::from_option(pgid))
)
})
.and_then(|e| Pid::try_from(e as u32))
}
@ -404,7 +408,7 @@ pub fn sys_getgid() -> GroupId {
#[inline(always)]
pub fn sys_setsid() -> Result<Pid, Errno> {
Errno::from_syscall(unsafe { syscall!(SystemCall::SetSid) })
.and_then(|e| Pid::try_from(e as u32) )
.and_then(|e| Pid::try_from(e as u32))
}
#[inline(always)]

View File

@ -58,8 +58,8 @@ impl From<ExitCode> for i32 {
}
impl Pid {
/// Kernel idle process always has PID of zero
pub const IDLE: Self = Self(Self::KERNEL_BIT);
// /// Kernel idle process always has PID of zero
// pub const IDLE: Self = Self(Self::KERNEL_BIT);
const KERNEL_BIT: u32 = 1 << 31;
const USER_MAX: u32 = 256;
@ -101,7 +101,11 @@ impl Pid {
}
pub fn to_option(m: u32) -> Option<Self> {
todo!()
if m != 0 {
Some(Self::try_from(m).unwrap())
} else {
None
}
}
}
@ -159,3 +163,25 @@ impl From<Pgid> for u32 {
p.0
}
}
impl Tid {
pub const IDLE: Tid = Tid(0);
}
impl fmt::Debug for Tid {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Tid(#{})", self.0)
}
}
impl From<u32> for Tid {
fn from(p: u32) -> Tid {
Self(p)
}
}
impl From<Tid> for u32 {
fn from(p: Tid) -> u32 {
p.0
}
}

View File

@ -6,7 +6,7 @@ use core::fmt;
use core::mem::MaybeUninit;
use libsys::{
calls::{sys_ex_clone, sys_ex_gettid, sys_ex_signal, sys_ex_thread_exit, sys_ex_thread_wait},
proc::ExitCode,
proc::{ExitCode, Tid},
};
struct NativeData<F, T>
@ -22,19 +22,19 @@ where
#[derive(Clone)]
pub struct Thread {
id: u32,
id: Tid,
}
pub type ThreadResult<T> = Result<T, Box<dyn Any + Send + Sync>>;
pub type ThreadPacket<T> = Arc<UnsafeCell<MaybeUninit<ThreadResult<T>>>>;
pub struct JoinHandle<T> {
native: u32,
native: Tid,
result: ThreadPacket<T>,
}
impl Thread {
pub const fn id(&self) -> u32 {
pub const fn id(&self) -> Tid {
self.id
}
}
@ -60,7 +60,7 @@ impl<T> JoinHandle<T> {
}
unsafe fn init_common(signal_stack_pointer: *mut u8) {
let tid = sys_ex_gettid() as u64;
let tid = u32::from(sys_ex_gettid()) as u64;
asm!("msr tpidr_el0, {:x}", in(reg) tid);
// thread::current() should be valid at this point
@ -86,8 +86,7 @@ pub fn current() -> Thread {
unsafe {
asm!("mrs {:x}, tpidr_el0", out(reg) id);
}
Thread { id: id as u32 }
Thread { id: Tid::from(id as u32) }
}
pub fn spawn<F, T>(f: F) -> JoinHandle<T>
@ -136,7 +135,7 @@ where
result: result.clone(),
}));
sys_ex_clone(thread_entry::<F, T> as usize, stack, data as usize).unwrap() as u32
sys_ex_clone(thread_entry::<F, T> as usize, stack, data as usize).unwrap()
};
JoinHandle { native, result }

View File

@ -9,7 +9,7 @@ use alloc::{borrow::ToOwned, vec::Vec};
use libusr::io::{self, Read};
use libusr::signal::{self, SignalHandler};
use libusr::sys::{
proc::Pid, sys_chdir, sys_execve, sys_exit, sys_faccessat, sys_fork, sys_getpgid, sys_setpgid,
sys_chdir, sys_execve, sys_exit, sys_faccessat, sys_fork, sys_getpgid, sys_setpgid,
sys_waitpid, AccessMode, Errno, ExitCode, FileDescriptor, Signal,
};

View File

@ -11,7 +11,6 @@ use libsys::{
},
error::Errno,
ioctl::IoctlCmd,
proc::Pid,
stat::{FileDescriptor, FileMode, GroupId, OpenFlags, UserId},
termios::{Termios, TermiosLflag},
};