From 5b9c821ff5d1fbcf3c9f2b28ddcc5b936c694297 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sat, 20 Aug 2016 14:32:45 -0600 Subject: [PATCH] Initialize contexts, add getpid --- kernel/context/mod.rs | 18 ++++++++++++++---- kernel/lib.rs | 8 ++++++-- kernel/syscall/mod.rs | 6 +++++- kernel/syscall/process.rs | 13 ++++++++++++- 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/kernel/context/mod.rs b/kernel/context/mod.rs index 29aa094..30feb93 100644 --- a/kernel/context/mod.rs +++ b/kernel/context/mod.rs @@ -37,7 +37,7 @@ impl ContextList { self.map.get(&CONTEXT_ID.load(Ordering::SeqCst)) } - pub fn new_context(&mut self) -> Result<(usize, &RwLock)> { + pub fn new_context(&mut self) -> Result<&RwLock> { if self.next_id >= CONTEXT_MAX_CONTEXTS { self.next_id = 1; } @@ -52,8 +52,8 @@ impl ContextList { let id = self.next_id; self.next_id += 1; - assert!(self.map.insert(id, RwLock::new(Context::new())).is_none()); - Ok((id, self.map.get(&id).expect("failed to insert new context"))) + assert!(self.map.insert(id, RwLock::new(Context::new(id))).is_none()); + Ok(self.map.get(&id).expect("failed to insert new context")) } } @@ -63,6 +63,13 @@ static CONTEXTS: Once> = Once::new(); #[thread_local] static CONTEXT_ID: AtomicUsize = ATOMIC_USIZE_INIT; +pub fn init() { + let mut contexts = contexts_mut(); + let context_lock = contexts.new_context().expect("could not initialize first context"); + let context = context_lock.read(); + CONTEXT_ID.store(context.id, Ordering::SeqCst); +} + /// Initialize contexts, called if needed fn init_contexts() -> RwLock { RwLock::new(ContextList::new()) @@ -81,13 +88,16 @@ pub fn contexts_mut() -> RwLockWriteGuard<'static, ContextList> { /// A context, which identifies either a process or a thread #[derive(Debug)] pub struct Context { + /// The ID of this context + pub id: usize, /// The open files in the scheme pub files: Vec> } impl Context { - pub fn new() -> Context { + pub fn new(id: usize) -> Context { Context { + id: id, files: Vec::new() } } diff --git a/kernel/lib.rs b/kernel/lib.rs index 88ca1d0..a5aa1fe 100644 --- a/kernel/lib.rs +++ b/kernel/lib.rs @@ -112,7 +112,9 @@ pub mod tests; #[no_mangle] pub extern fn kmain() { - print!("{}", format!("BSP\n")); + context::init(); + + print!("{}", format!("BSP: {:?}\n", syscall::getpid())); loop { unsafe { interrupt::enable_and_halt(); } @@ -121,7 +123,9 @@ pub extern fn kmain() { #[no_mangle] pub extern fn kmain_ap(id: usize) { - print!("{}", format!("AP {}\n", id)); + context::init(); + + print!("{}", format!("AP {}: {:?}\n", id, syscall::getpid())); loop { unsafe { interrupt::enable_and_halt() } diff --git a/kernel/syscall/mod.rs b/kernel/syscall/mod.rs index edc924d..f42a431 100644 --- a/kernel/syscall/mod.rs +++ b/kernel/syscall/mod.rs @@ -28,6 +28,8 @@ pub enum Call { Close = 6, /// Execute syscall Exec = 11, + /// Get process ID + GetPid = 20, } /// Convert numbers to calls @@ -41,6 +43,7 @@ impl Call { 5 => Ok(Call::Open), 6 => Ok(Call::Close), 11 => Ok(Call::Exec), + 20 => Ok(Call::GetPid), _ => Err(Error::NoCall) } } @@ -90,7 +93,8 @@ pub fn handle(a: usize, b: usize, c: usize, d: usize, e: usize, _f: usize) -> Re Call::Write => write(b, convert_slice(c as *const u8, d)?), Call::Open => open(convert_slice(b as *const u8, c)?, d), Call::Close => close(b), - Call::Exec => exec(convert_slice(b as *const u8, c)?, convert_slice(d as *const [usize; 2], e)?) + Call::Exec => exec(convert_slice(b as *const u8, c)?, convert_slice(d as *const [usize; 2], e)?), + Call::GetPid => getpid(), } } diff --git a/kernel/syscall/process.rs b/kernel/syscall/process.rs index 6daf73a..4f43aee 100644 --- a/kernel/syscall/process.rs +++ b/kernel/syscall/process.rs @@ -2,7 +2,9 @@ use arch::interrupt::halt; -use super::{convert_slice, Result}; +use context; + +use super::{convert_slice, Error, Result}; pub fn exit(status: usize) -> ! { println!("Exit {}", status); @@ -19,3 +21,12 @@ pub fn exec(path: &[u8], args: &[[usize; 2]]) -> Result { println!(""); Ok(0) } + +pub fn getpid() -> Result { + if let Some(context_lock) = context::contexts().current() { + let context = context_lock.read(); + Ok(context.id) + } else { + Err(Error::NoProcess) + } +}