diff --git a/src/arch/aarch64/interrupt/irq.rs b/src/arch/aarch64/interrupt/irq.rs index a21bf47adc..a11a03edb2 100644 --- a/src/arch/aarch64/interrupt/irq.rs +++ b/src/arch/aarch64/interrupt/irq.rs @@ -9,9 +9,6 @@ use crate::time; use crate::{exception_stack}; -//resets to 0 in context::switch() -pub static PIT_TICKS: AtomicUsize = ATOMIC_USIZE_INIT; - exception_stack!(irq_at_el0, |stack| { match gic::irq_ack() { 30 => irq_handler_gentimer(30), @@ -56,10 +53,8 @@ pub unsafe fn irq_handler_gentimer(irq: u32) { timeout::trigger(); - // Switch after 3 ticks (about 6.75 ms) - if PIT_TICKS.fetch_add(1, Ordering::SeqCst) >= 2 { - let _ = context::switch(); - } + context::switch::tick(); + trigger(irq); GENTIMER.reload_count(); } diff --git a/src/arch/x86/interrupt/ipi.rs b/src/arch/x86/interrupt/ipi.rs index fd70507aca..013dd23b77 100644 --- a/src/arch/x86/interrupt/ipi.rs +++ b/src/arch/x86/interrupt/ipi.rs @@ -1,9 +1,7 @@ -use core::sync::atomic::Ordering; use x86::tlb; use crate::context; use crate::device::local_apic::LOCAL_APIC; -use super::irq::PIT_TICKS; interrupt!(wakeup, || { LOCAL_APIC.eoi(); @@ -24,8 +22,6 @@ interrupt!(switch, || { interrupt!(pit, || { LOCAL_APIC.eoi(); - // Switch after 3 ticks (about 6.75 ms) - if PIT_TICKS.fetch_add(1, Ordering::SeqCst) >= 2 { - let _ = context::switch(); - } + // Switch after a sufficent amount of time since the last switch. + context::switch::tick(); }); diff --git a/src/arch/x86/interrupt/irq.rs b/src/arch/x86/interrupt/irq.rs index 79729cd818..8fc7cafa08 100644 --- a/src/arch/x86/interrupt/irq.rs +++ b/src/arch/x86/interrupt/irq.rs @@ -11,10 +11,6 @@ use crate::scheme::debug::{debug_input, debug_notify}; use crate::scheme::serio::serio_input; use crate::{context, time}; -//resets to 0 in context::switch() -#[thread_local] -pub static PIT_TICKS: AtomicUsize = AtomicUsize::new(0); - #[repr(u8)] #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum IrqMethod { @@ -149,10 +145,8 @@ interrupt_stack!(pit_stack, |_stack| { // Any better way of doing this? timeout::trigger(); - // Switch after 3 ticks (about 6.75 ms) - if PIT_TICKS.fetch_add(1, Ordering::SeqCst) >= 2 { - let _ = context::switch(); - } + // Switch after a sufficent amount of time since the last switch. + context::switch::tick(); }); interrupt!(keyboard, || { diff --git a/src/arch/x86_64/interrupt/ipi.rs b/src/arch/x86_64/interrupt/ipi.rs index fd70507aca..fefbd8c02a 100644 --- a/src/arch/x86_64/interrupt/ipi.rs +++ b/src/arch/x86_64/interrupt/ipi.rs @@ -1,9 +1,7 @@ -use core::sync::atomic::Ordering; use x86::tlb; use crate::context; use crate::device::local_apic::LOCAL_APIC; -use super::irq::PIT_TICKS; interrupt!(wakeup, || { LOCAL_APIC.eoi(); @@ -24,8 +22,6 @@ interrupt!(switch, || { interrupt!(pit, || { LOCAL_APIC.eoi(); - // Switch after 3 ticks (about 6.75 ms) - if PIT_TICKS.fetch_add(1, Ordering::SeqCst) >= 2 { - let _ = context::switch(); - } + // Switch after a sufficient amount of time since the last switch. + context::switch::tick(); }); diff --git a/src/arch/x86_64/interrupt/irq.rs b/src/arch/x86_64/interrupt/irq.rs index 79729cd818..ff944568a0 100644 --- a/src/arch/x86_64/interrupt/irq.rs +++ b/src/arch/x86_64/interrupt/irq.rs @@ -11,10 +11,6 @@ use crate::scheme::debug::{debug_input, debug_notify}; use crate::scheme::serio::serio_input; use crate::{context, time}; -//resets to 0 in context::switch() -#[thread_local] -pub static PIT_TICKS: AtomicUsize = AtomicUsize::new(0); - #[repr(u8)] #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum IrqMethod { @@ -149,10 +145,8 @@ interrupt_stack!(pit_stack, |_stack| { // Any better way of doing this? timeout::trigger(); - // Switch after 3 ticks (about 6.75 ms) - if PIT_TICKS.fetch_add(1, Ordering::SeqCst) >= 2 { - let _ = context::switch(); - } + // Switch after a sufficient amount of time since the last switch. + context::switch::tick(); }); interrupt!(keyboard, || { diff --git a/src/context/mod.rs b/src/context/mod.rs index 40e17f5463..6b742357d6 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -34,7 +34,7 @@ pub mod context; mod list; /// Context switch function -mod switch; +pub mod switch; /// File struct - defines a scheme and a file number pub mod file; diff --git a/src/context/switch.rs b/src/context/switch.rs index 2a2d31cf04..e49a2b2166 100644 --- a/src/context/switch.rs +++ b/src/context/switch.rs @@ -10,7 +10,6 @@ use crate::context::signal::signal_handler; use crate::context::{arch, contexts, Context, CONTEXT_ID}; #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] use crate::gdt; -use crate::interrupt::irq::PIT_TICKS; use crate::interrupt; use crate::ptrace; use crate::time; @@ -91,6 +90,20 @@ struct SwitchResult { #[thread_local] static SWITCH_RESULT: Cell> = Cell::new(None); +//resets to 0 in context::switch() +#[thread_local] +pub static PIT_TICKS: Cell = Cell::new(0); + +pub fn tick() { + let new_ticks = PIT_TICKS.get() + 1; + PIT_TICKS.set(new_ticks); + + // Switch after 3 ticks (about 6.75 ms) + if new_ticks >= 3 { + let _ = unsafe { switch() }; + } +} + pub unsafe extern "C" fn switch_finish_hook() { if let Some(SwitchResult { prev_lock, next_lock }) = SWITCH_RESULT.take() { prev_lock.force_write_unlock(); @@ -110,7 +123,7 @@ pub unsafe extern "C" fn switch_finish_hook() { pub unsafe fn switch() -> bool { // TODO: Better memory orderings? //set PIT Interrupt counter to 0, giving each process same amount of PIT ticks - let _ticks = PIT_TICKS.swap(0, Ordering::SeqCst); + PIT_TICKS.set(0); // Set the global lock to avoid the unsafe operations below from causing issues while arch::CONTEXT_SWITCH_LOCK.compare_exchange_weak(false, true, Ordering::SeqCst, Ordering::Relaxed).is_err() {