Permalink
Browse files

Remove SwitchResult, use out of band data to detect interruption

Update debugging code
  • Loading branch information...
jackpot51 committed Nov 15, 2017
1 parent da95409 commit ed055640119d7078d9b9ec1aea6ebc99dd1c6a43
Showing with 68 additions and 62 deletions.
  1. +1 −1 src/context/mod.rs
  2. +14 −28 src/context/switch.rs
  3. +10 −17 src/lib.rs
  4. +3 −6 src/scheme/pipe.rs
  5. +33 −4 src/sync/wait_condition.rs
  6. +7 −6 src/syscall/mod.rs
View
@@ -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;
View
@@ -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
}
}
View
@@ -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();
}
}
}
View
@@ -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));
}
}
}
View
@@ -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,20 +25,49 @@ impl WaitCondition {
len
}
pub fn wait(&self) -> SwitchResult {
pub fn wait(&self) -> bool {
let id;
{
let context_lock = {
let contexts = context::contexts();
let context_lock = contexts.current().expect("WaitCondition::wait: no context");
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
}
}
View
@@ -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);
}
}
}

0 comments on commit ed05564

Please sign in to comment.