mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-22 17:03:23 +00:00
Reimplement the DisableLocalIrqGuard
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
78de1af348
commit
7401eee455
@ -197,60 +197,24 @@ pub fn disable_local() -> DisabledLocalIrqGuard {
|
|||||||
|
|
||||||
/// A guard for disabled local IRQs.
|
/// A guard for disabled local IRQs.
|
||||||
pub struct DisabledLocalIrqGuard {
|
pub struct DisabledLocalIrqGuard {
|
||||||
// Having a private field prevents user from constructing values of this type directly.
|
was_enabled: bool,
|
||||||
private: (),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl !Send for DisabledLocalIrqGuard {}
|
impl !Send for DisabledLocalIrqGuard {}
|
||||||
|
|
||||||
cpu_local! {
|
|
||||||
static IRQ_OFF_COUNT: IrqInfo = IrqInfo::new();
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DisabledLocalIrqGuard {
|
impl DisabledLocalIrqGuard {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
IRQ_OFF_COUNT.inc();
|
let was_enabled = irq::is_local_enabled();
|
||||||
Self { private: () }
|
if was_enabled {
|
||||||
|
irq::disable_local();
|
||||||
|
}
|
||||||
|
Self { was_enabled }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for DisabledLocalIrqGuard {
|
impl Drop for DisabledLocalIrqGuard {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
IRQ_OFF_COUNT.dec();
|
if self.was_enabled {
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
struct IrqInfo {
|
|
||||||
// interrupt disabling level
|
|
||||||
level: AtomicU32,
|
|
||||||
// interrupt state before calling dec()/inc()
|
|
||||||
is_irq_enabled: AtomicBool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IrqInfo {
|
|
||||||
const fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
level: AtomicU32::new(0),
|
|
||||||
is_irq_enabled: AtomicBool::new(false),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inc(&self) {
|
|
||||||
let enabled = irq::is_local_enabled();
|
|
||||||
let level = self.level.load(Relaxed);
|
|
||||||
if level == 0 {
|
|
||||||
self.is_irq_enabled.store(enabled, Relaxed);
|
|
||||||
}
|
|
||||||
if enabled {
|
|
||||||
irq::disable_local();
|
|
||||||
}
|
|
||||||
self.level.fetch_add(1, Relaxed);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dec(&self) {
|
|
||||||
let level = self.level.fetch_sub(1, Relaxed) - 1;
|
|
||||||
if level == 0 && self.is_irq_enabled.load(Relaxed) {
|
|
||||||
irq::enable_local();
|
irq::enable_local();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user