Move push_off()/pop_off() into trap.rs and rename to push_intr_off() and pop_intr_off()
This commit is contained in:
parent
c593250549
commit
a1f88ff034
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
proc::{mycpu, Cpu},
|
proc::{mycpu, Cpu},
|
||||||
riscv,
|
trap::{push_intr_off, pop_intr_off},
|
||||||
};
|
};
|
||||||
use core::{
|
use core::{
|
||||||
ffi::c_char,
|
ffi::c_char,
|
||||||
@ -37,7 +37,7 @@ impl Spinlock {
|
|||||||
self.cpu == unsafe { mycpu() } && self.locked.load(Ordering::Relaxed)
|
self.cpu == unsafe { mycpu() } && self.locked.load(Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
pub unsafe fn lock_unguarded(&self) {
|
pub unsafe fn lock_unguarded(&self) {
|
||||||
push_off();
|
push_intr_off();
|
||||||
|
|
||||||
if self.held_by_current_cpu() {
|
if self.held_by_current_cpu() {
|
||||||
panic!("Attempt to acquire twice by the same CPU");
|
panic!("Attempt to acquire twice by the same CPU");
|
||||||
@ -68,7 +68,7 @@ impl Spinlock {
|
|||||||
this.cpu = null_mut();
|
this.cpu = null_mut();
|
||||||
this.locked.store(false, Ordering::Release);
|
this.locked.store(false, Ordering::Release);
|
||||||
|
|
||||||
pop_off();
|
pop_intr_off();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,37 +100,3 @@ pub unsafe extern "C" fn acquire(lock: *mut Spinlock) {
|
|||||||
pub unsafe extern "C" fn release(lock: *mut Spinlock) {
|
pub unsafe extern "C" fn release(lock: *mut Spinlock) {
|
||||||
(*lock).unlock();
|
(*lock).unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
// push_off/pop_off are like intr_off()/intr_on() except that they are matched:
|
|
||||||
// it takes two pop_off()s to undo two push_off()s. Also, if interrupts
|
|
||||||
// are initially off, then push_off, pop_off leaves them off.
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn push_off() {
|
|
||||||
let old = riscv::intr_get();
|
|
||||||
let cpu = mycpu();
|
|
||||||
|
|
||||||
riscv::intr_off();
|
|
||||||
if (*cpu).interrupt_disable_layers == 0 {
|
|
||||||
(*cpu).previous_interrupts_enabled = old;
|
|
||||||
}
|
|
||||||
(*cpu).interrupt_disable_layers += 1;
|
|
||||||
}
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern "C" fn pop_off() {
|
|
||||||
let cpu = mycpu();
|
|
||||||
|
|
||||||
if riscv::intr_get() == 1 {
|
|
||||||
// crate::panic_byte(b'0');
|
|
||||||
panic!("pop_off - interruptible");
|
|
||||||
} else if (*cpu).interrupt_disable_layers < 1 {
|
|
||||||
// crate::panic_byte(b'1');
|
|
||||||
panic!("pop_off");
|
|
||||||
}
|
|
||||||
|
|
||||||
(*cpu).interrupt_disable_layers -= 1;
|
|
||||||
|
|
||||||
if (*cpu).interrupt_disable_layers == 0 && (*cpu).previous_interrupts_enabled == 1 {
|
|
||||||
riscv::intr_on();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -17,13 +17,22 @@ impl<T> SpinMutex<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn lock(&self) -> SpinMutexGuard<'_, T> {
|
pub fn lock(&self) -> SpinMutexGuard<'_, T> {
|
||||||
|
unsafe {
|
||||||
|
crate::trap::push_intr_off();
|
||||||
|
}
|
||||||
|
|
||||||
while self.locked.swap(true, Ordering::Acquire) {
|
while self.locked.swap(true, Ordering::Acquire) {
|
||||||
core::hint::spin_loop();
|
core::hint::spin_loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
SpinMutexGuard { mutex: self }
|
SpinMutexGuard { mutex: self }
|
||||||
}
|
}
|
||||||
pub unsafe fn unlock(&self) {
|
pub unsafe fn unlock(&self) {
|
||||||
self.locked.store(false, Ordering::Release);
|
self.locked.store(false, Ordering::Release);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
crate::trap::pop_intr_off();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsafe impl<T> Sync for SpinMutex<T> where T: Send {}
|
unsafe impl<T> Sync for SpinMutex<T> where T: Send {}
|
||||||
|
@ -278,3 +278,37 @@ pub unsafe extern "C" fn usertrap() {
|
|||||||
|
|
||||||
usertrapret();
|
usertrapret();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// push_intr_off/pop_intr_off are like intr_off()/intr_on() except that they are matched:
|
||||||
|
// it takes two pop_intr_off()s to undo two push_intr_off()s. Also, if interrupts
|
||||||
|
// are initially off, then push_intr_off, pop_intr_off leaves them off.
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn push_intr_off() {
|
||||||
|
let old = crate::riscv::intr_get();
|
||||||
|
let cpu = mycpu();
|
||||||
|
|
||||||
|
crate::riscv::intr_off();
|
||||||
|
if (*cpu).interrupt_disable_layers == 0 {
|
||||||
|
(*cpu).previous_interrupts_enabled = old;
|
||||||
|
}
|
||||||
|
(*cpu).interrupt_disable_layers += 1;
|
||||||
|
}
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn pop_intr_off() {
|
||||||
|
let cpu = mycpu();
|
||||||
|
|
||||||
|
if crate::riscv::intr_get() == 1 {
|
||||||
|
// crate::panic_byte(b'0');
|
||||||
|
panic!("pop_intr_off - interruptible");
|
||||||
|
} else if (*cpu).interrupt_disable_layers < 1 {
|
||||||
|
// crate::panic_byte(b'1');
|
||||||
|
panic!("pop_intr_off");
|
||||||
|
}
|
||||||
|
|
||||||
|
(*cpu).interrupt_disable_layers -= 1;
|
||||||
|
|
||||||
|
if (*cpu).interrupt_disable_layers == 0 && (*cpu).previous_interrupts_enabled == 1 {
|
||||||
|
crate::riscv::intr_on();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user