diff --git a/kernel/context/context.rs b/kernel/context/context.rs index 4df574f..02ddb0c 100644 --- a/kernel/context/context.rs +++ b/kernel/context/context.rs @@ -9,6 +9,10 @@ use context::memory::{Grant, Memory, SharedMemory, Tls}; use syscall::data::Event; use sync::{WaitMap, WaitQueue}; +/// Unique identifier for a context (i.e. `pid`). +use ::core::sync::atomic::AtomicUsize; +int_like!(ContextId, AtomicContextId, usize, AtomicUsize); + /// The status of a context - used for scheduling /// See syscall::process::waitpid and the sync module for examples of usage #[derive(Copy, Clone, Debug, Eq, PartialEq)] @@ -22,9 +26,9 @@ pub enum Status { #[derive(Debug)] pub struct Context { /// The ID of this context - pub id: usize, + pub id: ContextId, /// The ID of the parent context - pub ppid: usize, + pub ppid: ContextId, /// The real user id pub ruid: u32, /// The real group id @@ -42,7 +46,7 @@ pub struct Context { /// Context is halting parent pub vfork: bool, /// Context is being waited on - pub waitpid: Arc>, + pub waitpid: Arc>, /// Context should wake up at specified time pub wake: Option<(u64, u64)>, /// The architecture specific context @@ -75,10 +79,10 @@ pub struct Context { impl Context { /// Create a new context - pub fn new(id: usize) -> Context { + pub fn new(id: ContextId) -> Context { Context { id: id, - ppid: 0, + ppid: ContextId::from(0), ruid: 0, rgid: 0, euid: 0, diff --git a/kernel/context/event.rs b/kernel/context/event.rs index b41a692..40f9efa 100644 --- a/kernel/context/event.rs +++ b/kernel/context/event.rs @@ -17,7 +17,7 @@ pub struct RegKey { #[derive(PartialEq, Eq, PartialOrd, Ord)] pub struct ProcessKey { - context_id: usize, + context_id: context::context::ContextId, fd: usize, } diff --git a/kernel/context/list.rs b/kernel/context/list.rs index 5541efa..11c25c2 100644 --- a/kernel/context/list.rs +++ b/kernel/context/list.rs @@ -7,11 +7,11 @@ use spin::RwLock; use arch; use syscall::error::{Result, Error, EAGAIN}; -use super::context::Context; +use super::context::{Context, ContextId}; /// Context list type pub struct ContextList { - map: BTreeMap>>, + map: BTreeMap>>, next_id: usize } @@ -25,7 +25,7 @@ impl ContextList { } /// Get the nth context. - pub fn get(&self, id: usize) -> Option<&Arc>> { + pub fn get(&self, id: ContextId) -> Option<&Arc>> { self.map.get(&id) } @@ -34,7 +34,7 @@ impl ContextList { self.map.get(&super::CONTEXT_ID.load(Ordering::SeqCst)) } - pub fn iter(&self) -> ::collections::btree_map::Iter>> { + pub fn iter(&self) -> ::collections::btree_map::Iter>> { self.map.iter() } @@ -44,7 +44,7 @@ impl ContextList { self.next_id = 1; } - while self.map.contains_key(&self.next_id) { + while self.map.contains_key(&ContextId::from(self.next_id)) { self.next_id += 1; } @@ -52,7 +52,7 @@ impl ContextList { return Err(Error::new(EAGAIN)); } - let id = self.next_id; + let id = ContextId::from(self.next_id); self.next_id += 1; assert!(self.map.insert(id, Arc::new(RwLock::new(Context::new(id)))).is_none()); @@ -85,7 +85,7 @@ impl ContextList { Ok(context_lock) } - pub fn remove(&mut self, id: usize) -> Option>> { + pub fn remove(&mut self, id: ContextId) -> Option>> { self.map.remove(&id) } } diff --git a/kernel/context/mod.rs b/kernel/context/mod.rs index d787eff..2b1214c 100644 --- a/kernel/context/mod.rs +++ b/kernel/context/mod.rs @@ -1,11 +1,12 @@ //! Context management use alloc::boxed::Box; -use core::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; +use core::sync::atomic::Ordering; use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard}; pub use self::context::{Context, Status}; pub use self::list::ContextList; pub use self::switch::switch; +pub use context::context::ContextId; /// Context struct mod context; @@ -35,7 +36,7 @@ pub const CONTEXT_MAX_FILES: usize = 65536; static CONTEXTS: Once> = Once::new(); #[thread_local] -static CONTEXT_ID: AtomicUsize = ATOMIC_USIZE_INIT; +static CONTEXT_ID: context::AtomicContextId = context::AtomicContextId::default(); pub fn init() { let mut contexts = contexts_mut(); @@ -69,6 +70,6 @@ pub fn contexts_mut() -> RwLockWriteGuard<'static, ContextList> { CONTEXTS.call_once(init_contexts).write() } -pub fn context_id() -> usize { +pub fn context_id() -> context::ContextId { CONTEXT_ID.load(Ordering::SeqCst) } diff --git a/kernel/lib.rs b/kernel/lib.rs index fadacba..db6a4aa 100644 --- a/kernel/lib.rs +++ b/kernel/lib.rs @@ -44,13 +44,13 @@ extern crate spin; use core::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; -/// Context management -pub mod context; - #[macro_use] +#[macro_export] /// Shared data structures pub mod common; +/// Context management +pub mod context; /// ELF file parsing #[cfg(all(not(test), target_arch = "x86_64"))] @@ -105,7 +105,7 @@ pub extern fn userspace_init() { /// Allow exception handlers to send signal to arch-independant kernel #[no_mangle] pub extern fn ksignal(signal: usize) { - println!("SIGNAL {}, CPU {}, PID {}", signal, cpu_id(), context::context_id()); + println!("SIGNAL {}, CPU {}, PID {:?}", signal, cpu_id(), context::context_id()); { let contexts = context::contexts(); if let Some(context_lock) = contexts.current() { diff --git a/kernel/scheme/sys/context.rs b/kernel/scheme/sys/context.rs index 75b5e4f..3f179b3 100644 --- a/kernel/scheme/sys/context.rs +++ b/kernel/scheme/sys/context.rs @@ -83,8 +83,8 @@ pub fn resource() -> Result> { let name = str::from_utf8(&name_bytes).unwrap_or(""); string.push_str(&format!("{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<8}{}\n", - context.id, - context.ppid, + context.id.into(), + context.ppid.into(), context.euid, context.egid, stat_string, diff --git a/kernel/scheme/user.rs b/kernel/scheme/user.rs index c918d9e..3a8c4af 100644 --- a/kernel/scheme/user.rs +++ b/kernel/scheme/user.rs @@ -53,7 +53,7 @@ impl UserInner { self.call_inner(Packet { id: self.next_id.fetch_add(1, Ordering::SeqCst), - pid: pid, + pid: pid.into(), uid: uid, gid: gid, a: a, @@ -297,7 +297,7 @@ impl Scheme for UserScheme { inner.call_inner(Packet { id: id, - pid: pid, + pid: pid.into(), uid: uid, gid: gid, a: SYS_FMAP, diff --git a/kernel/syscall/fs.rs b/kernel/syscall/fs.rs index 9aae871..d0ba198 100644 --- a/kernel/syscall/fs.rs +++ b/kernel/syscall/fs.rs @@ -25,7 +25,7 @@ pub fn file_op(a: usize, fd: usize, c: usize, d: usize) -> Result { let mut packet = Packet { id: 0, - pid: pid, + pid: pid.into(), uid: uid, gid: gid, a: a, diff --git a/kernel/syscall/mod.rs b/kernel/syscall/mod.rs index 952ccfa..2780655 100644 --- a/kernel/syscall/mod.rs +++ b/kernel/syscall/mod.rs @@ -14,6 +14,8 @@ use self::data::TimeSpec; use self::error::{Error, Result, ENOSYS}; use self::number::*; +use context::ContextId; + /// Filesystem syscalls pub mod fs; @@ -54,13 +56,13 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize }, _ => match a { SYS_EXIT => exit(b), - SYS_WAITPID => waitpid(b, c, d), + SYS_WAITPID => waitpid(ContextId::from(b), c, d).map(ContextId::into), SYS_EXECVE => exec(validate_slice(b as *const u8, c)?, validate_slice(d as *const [usize; 2], e)?), SYS_CHDIR => chdir(validate_slice(b as *const u8, c)?), - SYS_GETPID => getpid(), + SYS_GETPID => getpid().map(ContextId::into), SYS_BRK => brk(b), SYS_IOPL => iopl(b), - SYS_CLONE => clone(b, stack), + SYS_CLONE => clone(b, stack).map(ContextId::into), SYS_YIELD => sched_yield(), SYS_NANOSLEEP => nanosleep(validate_slice(b as *const TimeSpec, 1).map(|req| &req[0])?, validate_slice_mut(c as *mut TimeSpec, 1).ok().map(|rem| &mut rem[0])), SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?), diff --git a/kernel/syscall/process.rs b/kernel/syscall/process.rs index 9a65f6b..34ab02e 100644 --- a/kernel/syscall/process.rs +++ b/kernel/syscall/process.rs @@ -13,6 +13,7 @@ use arch::paging::{ActivePageTable, InactivePageTable, Page, PhysicalAddress, Vi use arch::paging::temporary_page::TemporaryPage; use arch::start::usermode; use context; +use context::ContextId; use context::memory::Grant; use elf::{self, program_header}; use scheme; @@ -54,7 +55,7 @@ pub fn brk(address: usize) -> Result { } } -pub fn clone(flags: usize, stack_base: usize) -> Result { +pub fn clone(flags: usize, stack_base: usize) -> Result { let ppid; let pid; { @@ -665,10 +666,10 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result { if let Some(context_lock) = contexts.get(ppid) { let mut context = context_lock.write(); if ! context.unblock() { - println!("{} not blocked for exec vfork unblock", ppid); + println!("{:?} not blocked for exec vfork unblock", ppid); } } else { - println!("{} not found for exec vfork unblock", ppid); + println!("{:?} not found for exec vfork unblock", ppid); } } }, @@ -756,7 +757,7 @@ pub fn exit(status: usize) -> ! { let mut parent = parent_lock.write(); if vfork { if ! parent.unblock() { - println!("{} not blocked for exit vfork unblock", ppid); + println!("{:?} not blocked for exit vfork unblock", ppid); } } parent.waitpid.clone() @@ -767,7 +768,7 @@ pub fn exit(status: usize) -> ! { } waitpid.send(pid, status); } else { - println!("{} not found for exit vfork unblock", ppid); + println!("{:?} not found for exit vfork unblock", ppid); } } } @@ -798,7 +799,7 @@ pub fn getgid() -> Result { Ok(context.rgid as usize) } -pub fn getpid() -> Result { +pub fn getpid() -> Result { let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; let context = context_lock.read(); @@ -817,7 +818,7 @@ pub fn iopl(_level: usize) -> Result { Ok(0) } -pub fn kill(pid: usize, sig: usize) -> Result { +pub fn kill(pid: ContextId, sig: usize) -> Result { use syscall::flag::*; let _context_lock = { @@ -827,19 +828,19 @@ pub fn kill(pid: usize, sig: usize) -> Result { }; let term = || { - println!("Terminate {}", pid); + println!("Terminate {:?}", pid); }; let core = || { - println!("Core {}", pid); + println!("Core {:?}", pid); }; let stop = || { - println!("Stop {}", pid); + println!("Stop {:?}", pid); }; let cont = || { - println!("Continue {}", pid); + println!("Continue {:?}", pid); }; match sig { @@ -1001,7 +1002,7 @@ pub fn virttophys(virtual_address: usize) -> Result { } } -fn reap(pid: usize) -> Result { +fn reap(pid: ContextId) -> Result { // Spin until not running let mut running = false; while running { @@ -1019,7 +1020,7 @@ fn reap(pid: usize) -> Result { contexts.remove(pid).ok_or(Error::new(ESRCH)).and(Ok(pid)) } -pub fn waitpid(pid: usize, status_ptr: usize, flags: usize) -> Result { +pub fn waitpid(pid: ContextId, status_ptr: usize, flags: usize) -> Result { let waitpid = { let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; @@ -1034,13 +1035,13 @@ pub fn waitpid(pid: usize, status_ptr: usize, flags: usize) -> Result { &mut tmp }; - if pid == 0 { + if pid.into() == 0 { if flags & WNOHANG == WNOHANG { if let Some((w_pid, status)) = waitpid.receive_any_nonblock() { status_slice[0] = status; reap(w_pid) } else { - Ok(0) + Ok(ContextId::from(0)) } } else { let (w_pid, status) = waitpid.receive_any(); @@ -1053,7 +1054,7 @@ pub fn waitpid(pid: usize, status_ptr: usize, flags: usize) -> Result { status_slice[0] = status; reap(pid) } else { - Ok(0) + Ok(ContextId::from(0)) } } else { let status = waitpid.receive(&pid);