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