forked from Bananymous/banan-os
Kernel: Move interrupt status functions to kernel/Interrupts.h
This commit is contained in:
parent
65c4f9db5b
commit
02ad199138
|
@ -5,9 +5,6 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define DISABLE_INTERRUPTS() asm volatile("cli")
|
|
||||||
#define ENABLE_INTERRUPTS() asm volatile("sti")
|
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -51,11 +48,4 @@ namespace Kernel
|
||||||
bool m_using_apic { false };
|
bool m_using_apic { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool interrupts_enabled()
|
|
||||||
{
|
|
||||||
uintptr_t flags;
|
|
||||||
asm volatile("pushf; pop %0" : "=r"(flags) :: "memory");
|
|
||||||
return flags & (1 << 9);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <kernel/Arch.h>
|
||||||
|
|
||||||
|
namespace Kernel
|
||||||
|
{
|
||||||
|
|
||||||
|
enum class InterruptState
|
||||||
|
{
|
||||||
|
Disabled,
|
||||||
|
Enabled,
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ARCH(x86_64) || ARCH(i386)
|
||||||
|
|
||||||
|
inline void set_interrupt_state(InterruptState state)
|
||||||
|
{
|
||||||
|
if (state == InterruptState::Enabled)
|
||||||
|
asm volatile("sti");
|
||||||
|
else
|
||||||
|
asm volatile("cli");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline InterruptState get_interrupt_state()
|
||||||
|
{
|
||||||
|
uintptr_t flags;
|
||||||
|
asm volatile("pushf; pop %0" : "=rm"(flags));
|
||||||
|
if (flags & (1 << 9))
|
||||||
|
return InterruptState::Enabled;
|
||||||
|
return InterruptState::Disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "Unknown architecure"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
|
@ -2,14 +2,13 @@
|
||||||
|
|
||||||
#include <BAN/Atomic.h>
|
#include <BAN/Atomic.h>
|
||||||
#include <BAN/NoCopyMove.h>
|
#include <BAN/NoCopyMove.h>
|
||||||
|
#include <kernel/Interrupts.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
using InterruptState = bool;
|
|
||||||
|
|
||||||
class SpinLock
|
class SpinLock
|
||||||
{
|
{
|
||||||
BAN_NON_COPYABLE(SpinLock);
|
BAN_NON_COPYABLE(SpinLock);
|
||||||
|
|
|
@ -12,8 +12,8 @@ namespace Kernel
|
||||||
auto tid = Scheduler::current_tid();
|
auto tid = Scheduler::current_tid();
|
||||||
ASSERT_NEQ(m_locker.load(), tid);
|
ASSERT_NEQ(m_locker.load(), tid);
|
||||||
|
|
||||||
InterruptState state = interrupts_enabled();
|
auto state = get_interrupt_state();
|
||||||
DISABLE_INTERRUPTS();
|
set_interrupt_state(InterruptState::Disabled);
|
||||||
|
|
||||||
if (!m_locker.compare_exchange(-1, tid))
|
if (!m_locker.compare_exchange(-1, tid))
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
|
@ -25,16 +25,15 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
ASSERT_EQ(m_locker.load(), Scheduler::current_tid());
|
ASSERT_EQ(m_locker.load(), Scheduler::current_tid());
|
||||||
m_locker.store(-1);
|
m_locker.store(-1);
|
||||||
if (state)
|
set_interrupt_state(state);
|
||||||
ENABLE_INTERRUPTS();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InterruptState RecursiveSpinLock::lock()
|
InterruptState RecursiveSpinLock::lock()
|
||||||
{
|
{
|
||||||
auto tid = Scheduler::current_tid();
|
auto tid = Scheduler::current_tid();
|
||||||
|
|
||||||
InterruptState state = interrupts_enabled();
|
auto state = get_interrupt_state();
|
||||||
DISABLE_INTERRUPTS();
|
set_interrupt_state(InterruptState::Disabled);
|
||||||
|
|
||||||
if (tid == m_locker)
|
if (tid == m_locker)
|
||||||
ASSERT_GT(m_lock_depth, 0);
|
ASSERT_GT(m_lock_depth, 0);
|
||||||
|
@ -57,8 +56,7 @@ namespace Kernel
|
||||||
ASSERT_GT(m_lock_depth, 0);
|
ASSERT_GT(m_lock_depth, 0);
|
||||||
if (--m_lock_depth == 0)
|
if (--m_lock_depth == 0)
|
||||||
m_locker = -1;
|
m_locker = -1;
|
||||||
if (state)
|
set_interrupt_state(state);
|
||||||
ENABLE_INTERRUPTS();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -220,7 +220,7 @@ namespace Kernel
|
||||||
|
|
||||||
void Process::on_thread_exit(Thread& thread)
|
void Process::on_thread_exit(Thread& thread)
|
||||||
{
|
{
|
||||||
ASSERT(!interrupts_enabled());
|
ASSERT(get_interrupt_state() == InterruptState::Disabled);
|
||||||
|
|
||||||
ASSERT(m_threads.size() > 0);
|
ASSERT(m_threads.size() > 0);
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
#define SCHEDULER_VERIFY_INTERRUPT_STATE 1
|
#define SCHEDULER_VERIFY_INTERRUPT_STATE 1
|
||||||
|
|
||||||
#if SCHEDULER_VERIFY_INTERRUPT_STATE
|
#if SCHEDULER_VERIFY_INTERRUPT_STATE
|
||||||
#define VERIFY_STI() ASSERT(interrupts_enabled())
|
#define VERIFY_STI() ASSERT(get_interrupt_state() == InterruptState::Enabled)
|
||||||
#define VERIFY_CLI() ASSERT(!interrupts_enabled())
|
#define VERIFY_CLI() ASSERT(get_interrupt_state() == InterruptState::Disabled)
|
||||||
#else
|
#else
|
||||||
#define VERIFY_STI()
|
#define VERIFY_STI()
|
||||||
#define VERIFY_CLI()
|
#define VERIFY_CLI()
|
||||||
|
@ -84,13 +84,10 @@ namespace Kernel
|
||||||
|
|
||||||
void Scheduler::reschedule()
|
void Scheduler::reschedule()
|
||||||
{
|
{
|
||||||
DISABLE_INTERRUPTS();
|
set_interrupt_state(InterruptState::Disabled);
|
||||||
|
|
||||||
if (save_current_thread())
|
if (save_current_thread())
|
||||||
{
|
return set_interrupt_state(InterruptState::Enabled);
|
||||||
ENABLE_INTERRUPTS();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
advance_current_thread();
|
advance_current_thread();
|
||||||
execute_current_thread();
|
execute_current_thread();
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
|
@ -190,7 +187,7 @@ namespace Kernel
|
||||||
|
|
||||||
void Scheduler::delete_current_process_and_thread()
|
void Scheduler::delete_current_process_and_thread()
|
||||||
{
|
{
|
||||||
DISABLE_INTERRUPTS();
|
set_interrupt_state(InterruptState::Disabled);
|
||||||
|
|
||||||
load_temp_stack();
|
load_temp_stack();
|
||||||
PageTable::kernel().load();
|
PageTable::kernel().load();
|
||||||
|
@ -285,7 +282,7 @@ namespace Kernel
|
||||||
|
|
||||||
if (save_current_thread())
|
if (save_current_thread())
|
||||||
{
|
{
|
||||||
ENABLE_INTERRUPTS();
|
set_interrupt_state(InterruptState::Enabled);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,7 +308,7 @@ namespace Kernel
|
||||||
void Scheduler::set_current_thread_sleeping(uint64_t wake_time)
|
void Scheduler::set_current_thread_sleeping(uint64_t wake_time)
|
||||||
{
|
{
|
||||||
VERIFY_STI();
|
VERIFY_STI();
|
||||||
DISABLE_INTERRUPTS();
|
set_interrupt_state(InterruptState::Disabled);
|
||||||
|
|
||||||
ASSERT(m_current_thread);
|
ASSERT(m_current_thread);
|
||||||
|
|
||||||
|
@ -322,7 +319,7 @@ namespace Kernel
|
||||||
void Scheduler::block_current_thread(Semaphore* semaphore, uint64_t wake_time)
|
void Scheduler::block_current_thread(Semaphore* semaphore, uint64_t wake_time)
|
||||||
{
|
{
|
||||||
VERIFY_STI();
|
VERIFY_STI();
|
||||||
DISABLE_INTERRUPTS();
|
set_interrupt_state(InterruptState::Disabled);
|
||||||
|
|
||||||
ASSERT(m_current_thread);
|
ASSERT(m_current_thread);
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ extern "C" void kernel_main(uint32_t boot_magic, uint32_t boot_info)
|
||||||
{
|
{
|
||||||
using namespace Kernel;
|
using namespace Kernel;
|
||||||
|
|
||||||
DISABLE_INTERRUPTS();
|
set_interrupt_state(InterruptState::Disabled);
|
||||||
|
|
||||||
if (!validate_boot_magic(boot_magic))
|
if (!validate_boot_magic(boot_magic))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue