From e7a4b786b0f784111c73236c766aa10830dc70cd Mon Sep 17 00:00:00 2001
From: Jeremy Soller <jackpot51@gmail.com>
Date: Sun, 23 Oct 2016 11:24:10 -0600
Subject: [PATCH] Add CPU ID lock

---
 context/context.rs |  3 +++
 context/mod.rs     |  1 +
 context/switch.rs  | 24 +++++++++++++-----------
 3 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/context/context.rs b/context/context.rs
index fd51e969..c280dae5 100644
--- a/context/context.rs
+++ b/context/context.rs
@@ -35,6 +35,8 @@ pub struct Context {
     pub status: Status,
     /// Context running or not
     pub running: bool,
+    /// CPU ID, if locked
+    pub cpuid: Option<usize>,
     /// Context is halting parent
     pub vfork: bool,
     /// Context is being waited on
@@ -79,6 +81,7 @@ impl Context {
             egid: 0,
             status: Status::Blocked,
             running: false,
+            cpuid: None,
             vfork: false,
             waitpid: Arc::new(WaitCondition::new()),
             wake: None,
diff --git a/context/mod.rs b/context/mod.rs
index 9da1259c..882eb6c9 100644
--- a/context/mod.rs
+++ b/context/mod.rs
@@ -50,6 +50,7 @@ pub fn init() {
     context.kfx = Some(fx);
     context.status = Status::Runnable;
     context.running = true;
+    context.cpuid = Some(::cpu_id());
     CONTEXT_ID.store(context.id, Ordering::SeqCst);
 }
 
diff --git a/context/switch.rs b/context/switch.rs
index 0e291e61..ccc51767 100644
--- a/context/switch.rs
+++ b/context/switch.rs
@@ -27,20 +27,22 @@ pub unsafe fn switch() -> bool {
         }
 
         let check_context = |context: &mut Context| -> bool {
-            if context.status == Status::Blocked && context.wake.is_some() {
-                let wake = context.wake.expect("context::switch: wake not set");
+            if context.cpuid == None || context.cpuid == Some(::cpu_id()) {
+                if context.status == Status::Blocked && context.wake.is_some() {
+                    let wake = context.wake.expect("context::switch: wake not set");
 
-                let current = arch::time::monotonic();
-                if current.0 > wake.0 || (current.0 == wake.0 && current.1 >= wake.1) {
-                    context.unblock();
+                    let current = arch::time::monotonic();
+                    if current.0 > wake.0 || (current.0 == wake.0 && current.1 >= wake.1) {
+                        context.unblock();
+                    }
                 }
-            }
 
-            if context.status == Status::Runnable && ! context.running {
-                true
-            } else {
-                false
+                if context.status == Status::Runnable && ! context.running {
+                    return true;
+                }
             }
+
+            false
         };
 
         for (pid, context_lock) in contexts.iter() {
@@ -72,7 +74,7 @@ pub unsafe fn switch() -> bool {
         return false;
     }
 
-    //println!("Switch {} to {}", (&*from_ptr).id, (&*to_ptr).id);
+    // println!("{}: Switch {} to {}", ::cpu_id(), (&*from_ptr).id, (&*to_ptr).id);
 
     (&mut *from_ptr).running = false;
     (&mut *to_ptr).running = true;
-- 
GitLab