#include #include #include #include void irq_set_state(bool state) { arch_irq_set_state(state); } bool irq_get_state() { return arch_irq_get_state(); } void irq_wait() { arch_irq_wait(); } void irq_lock() { struct irq_percpu* cpu = &percpu_get()->irq; if (atomic_load(&cpu->in_interrupt, ATOMIC_ACQUIRE)) return; arch_irq_set_state(false); atomic_fetch_add(&percpu_get()->irq.level, 1, ATOMIC_ACQ_REL); } void irq_unlock() { struct irq_percpu* cpu = &percpu_get()->irq; if (atomic_load(&cpu->in_interrupt, ATOMIC_ACQUIRE)) return; uint32_t old_level = atomic_fetch_sub(&cpu->level, 1, ATOMIC_ACQ_REL); // If it was 1, the new IRQ level is now 0. if (old_level == 1) { arch_irq_set_state(true); } } bool irq_set_interrupted(bool is_interrupted) { return atomic_exchange(&percpu_get()->irq.in_interrupt, is_interrupted, ATOMIC_RELEASE); }