From ed055640119d7078d9b9ec1aea6ebc99dd1c6a43 Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Tue, 14 Nov 2017 21:16:35 -0700 Subject: [PATCH] Remove SwitchResult, use out of band data to detect interruption Update debugging code --- src/context/mod.rs | 2 +- src/context/switch.rs | 42 +++++++++++++------------------------- src/lib.rs | 27 +++++++++--------------- src/scheme/pipe.rs | 9 +++----- src/sync/wait_condition.rs | 37 +++++++++++++++++++++++++++++---- src/syscall/mod.rs | 13 ++++++------ 6 files changed, 68 insertions(+), 62 deletions(-) diff --git a/src/context/mod.rs b/src/context/mod.rs index 62ef93a0..f0e428c1 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -7,7 +7,7 @@ use spin::{Once, RwLock, RwLockReadGuard, RwLockWriteGuard}; pub use self::context::{Context, ContextId, Status}; pub use self::list::ContextList; -pub use self::switch::{switch, SwitchResult}; +pub use self::switch::switch; #[path = "arch/x86_64.rs"] mod arch; diff --git a/src/context/switch.rs b/src/context/switch.rs index 91ac6f2d..28b06965 100644 --- a/src/context/switch.rs +++ b/src/context/switch.rs @@ -10,22 +10,12 @@ use interrupt::irq::PIT_TICKS; use syscall; use time; -#[must_use] -pub enum SwitchResult { - /// No context to switch to - None, - /// Received a signal - Signal, - /// Switched correctly - Normal, -} - /// Switch to the next context /// /// # Safety /// /// Do not call this while holding locks! -pub unsafe fn switch() -> SwitchResult { +pub unsafe fn switch() -> bool { use core::ops::DerefMut; //set PIT Interrupt counter to 0, giving each process same amount of PIT ticks @@ -148,28 +138,24 @@ pub unsafe fn switch() -> SwitchResult { if to_ptr as usize == 0 { // No target was found, return - SwitchResult::None - } else if let Some(sig) = to_sig { - // Signal was found, run signal handler - - //TODO: Allow nested signals - assert!((&mut *to_ptr).ksig.is_none()); - - let arch = (&mut *to_ptr).arch.clone(); - let kfx = (&mut *to_ptr).kfx.clone(); - let kstack = (&mut *to_ptr).kstack.clone(); - (&mut *to_ptr).ksig = Some((arch, kfx, kstack)); - (&mut *to_ptr).arch.signal_stack(signal_handler, sig); + false + } else { + if let Some(sig) = to_sig { + // Signal was found, run signal handler - (&mut *from_ptr).arch.switch_to(&mut (&mut *to_ptr).arch); + //TODO: Allow nested signals + assert!((&mut *to_ptr).ksig.is_none()); - SwitchResult::Signal - } else { - // Found a target, had no signals + let arch = (&mut *to_ptr).arch.clone(); + let kfx = (&mut *to_ptr).kfx.clone(); + let kstack = (&mut *to_ptr).kstack.clone(); + (&mut *to_ptr).ksig = Some((arch, kfx, kstack)); + (&mut *to_ptr).arch.signal_stack(signal_handler, sig); + } (&mut *from_ptr).arch.switch_to(&mut (&mut *to_ptr).arch); - SwitchResult::Normal + true } } diff --git a/src/lib.rs b/src/lib.rs index 6a509ef8..c6f40ee7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,7 +39,6 @@ use alloc::arc::Arc; use core::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; use spin::Mutex; -use context::SwitchResult; use scheme::{FileHandle, SchemeNamespace}; pub use consts::*; @@ -170,14 +169,11 @@ pub fn kmain(cpus: usize, env: &[u8]) -> ! { loop { unsafe { interrupt::disable(); - match context::switch() { - SwitchResult::None => { - // Enable interrupts, then halt CPU (to save power) until the next interrupt is actually fired. - interrupt::enable_and_halt(); - } - _ => { - interrupt::enable_and_nop(); - } + if context::switch() { + interrupt::enable_and_nop(); + } else { + // Enable interrupts, then halt CPU (to save power) until the next interrupt is actually fired. + interrupt::enable_and_halt(); } } } @@ -197,14 +193,11 @@ pub fn kmain_ap(id: usize) -> ! { loop { unsafe { interrupt::disable(); - match context::switch() { - SwitchResult::None => { - // Enable interrupts, then halt CPU (to save power) until the next interrupt is actually fired. - interrupt::enable_and_halt(); - } - _ => { - interrupt::enable_and_nop(); - } + if context::switch() { + interrupt::enable_and_nop(); + } else { + // Enable interrupts, then halt CPU (to save power) until the next interrupt is actually fired. + interrupt::enable_and_halt(); } } } diff --git a/src/scheme/pipe.rs b/src/scheme/pipe.rs index cf677601..fbbbb9eb 100644 --- a/src/scheme/pipe.rs +++ b/src/scheme/pipe.rs @@ -3,7 +3,7 @@ use alloc::{BTreeMap, VecDeque}; use core::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; use spin::{Mutex, Once, RwLock, RwLockReadGuard, RwLockWriteGuard}; -use context::{self, SwitchResult}; +use context; use scheme::{AtomicSchemeId, ATOMIC_SCHEMEID_INIT, SchemeId}; use sync::WaitCondition; use syscall::error::{Error, Result, EAGAIN, EBADF, EINTR, EINVAL, EPIPE, ESPIPE}; @@ -236,11 +236,8 @@ impl PipeRead { } else if self.flags.load(Ordering::SeqCst) & O_NONBLOCK == O_NONBLOCK { return Err(Error::new(EAGAIN)); } else { - match self.condition.wait() { - SwitchResult::Signal => { - return Err(Error::new(EINTR)); - }, - _ => () + if ! self.condition.wait() { + return Err(Error::new(EINTR)); } } } diff --git a/src/sync/wait_condition.rs b/src/sync/wait_condition.rs index 8c9a6a7c..500e8cd3 100644 --- a/src/sync/wait_condition.rs +++ b/src/sync/wait_condition.rs @@ -2,7 +2,7 @@ use alloc::arc::Arc; use alloc::Vec; use spin::{Mutex, RwLock}; -use context::{self, Context, SwitchResult}; +use context::{self, Context}; #[derive(Debug)] pub struct WaitCondition { @@ -25,7 +25,8 @@ impl WaitCondition { len } - pub fn wait(&self) -> SwitchResult { + pub fn wait(&self) -> bool { + let id; { let context_lock = { let contexts = context::contexts(); @@ -33,12 +34,40 @@ impl WaitCondition { context_lock.clone() }; - context_lock.write().block(); + { + let mut context = context_lock.write(); + id = context.id; + context.block(); + } self.contexts.lock().push(context_lock); } - unsafe { context::switch() } + unsafe { context::switch(); } + + let mut waited = true; + + { + let mut contexts = self.contexts.lock(); + + let mut i = 0; + while i < contexts.len() { + let remove = { + let context = contexts[i].read(); + context.id == id + }; + + if remove { + contexts.remove(i); + waited = false; + break; + } else { + i += 1; + } + } + } + + waited } } diff --git a/src/syscall/mod.rs b/src/syscall/mod.rs index 22e62b1c..793f23b2 100644 --- a/src/syscall/mod.rs +++ b/src/syscall/mod.rs @@ -142,7 +142,9 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize let contexts = ::context::contexts(); if let Some(context_lock) = contexts.current() { let context = context_lock.read(); - if unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) } == "file:/bin/acid" { + let name_raw = context.name.lock(); + let name = unsafe { ::core::str::from_utf8_unchecked(&name_raw) }; + if name == "file:/bin/cargo" || name == "file:/bin/rustc" { if (a == SYS_WRITE || a == SYS_FSYNC) && (b == 1 || b == 2) { false } else { @@ -163,8 +165,7 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize print!("{} ({}): ", unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) }, context.id.into()); } - let _ = debug::print_call(a, b, c, d, e, f); - println!(""); + println!("{}", debug::format_call(a, b, c, d, e, f)); } */ @@ -194,14 +195,14 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize print!("{} ({}): ", unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) }, context.id.into()); } - let _ = debug::print_call(a, b, c, d, e, f); + print!("{} = ", debug::format_call(a, b, c, d, e, f)); match result { Ok(ref ok) => { - println!(" = Ok({} ({:#X}))", ok, ok); + println!("Ok({} ({:#X}))", ok, ok); }, Err(ref err) => { - println!(" = Err({} ({:#X}))", err, err.errno); + println!("Err({} ({:#X}))", err, err.errno); } } } -- GitLab