Use weak CAS and use abort() in context::switch.

Previously context::switch used compare_and_swap for acquiring the
global context switch lock, but given its deprecation in more recent
Rust versions, it has been replaced with compare_exchange_weak (which
can be further optimized on some architectures).

It also replaces panic!() with abort() in switch_finish_hook, because
unwinding from assembly is not that fun.
This commit is contained in:
4lDO2
2021-03-19 11:07:41 +01:00
parent cc6f792a03
commit 7d4defa5e5

View File

@@ -78,7 +78,8 @@ pub unsafe extern "C" fn switch_finish_hook() {
prev_lock.force_write_unlock();
next_lock.force_write_unlock();
} else {
panic!("SWITCH_RESULT was not set");
// TODO: unreachable_unchecked()?
core::intrinsics::abort();
}
arch::CONTEXT_SWITCH_LOCK.store(false, Ordering::SeqCst);
}
@@ -97,11 +98,12 @@ unsafe fn runnable(context: &Context, cpu_id: usize) -> bool {
///
/// Do not call this while holding locks!
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);
// Set the global lock to avoid the unsafe operations below from causing issues
while arch::CONTEXT_SWITCH_LOCK.compare_and_swap(false, true, Ordering::SeqCst) {
while arch::CONTEXT_SWITCH_LOCK.compare_exchange_weak(false, true, Ordering::SeqCst, Ordering::Relaxed).is_err() {
interrupt::pause();
}