forked from Bananymous/banan-os
Kernel: Track the number of recursive spinlocks a thread is holding
This commit is contained in:
parent
56db0efe58
commit
81ff71a97f
|
@ -43,36 +43,11 @@ namespace Kernel
|
||||||
public:
|
public:
|
||||||
RecursiveSpinLock() = default;
|
RecursiveSpinLock() = default;
|
||||||
|
|
||||||
InterruptState lock()
|
InterruptState lock();
|
||||||
{
|
|
||||||
auto state = Processor::get_interrupt_state();
|
|
||||||
Processor::set_interrupt_state(InterruptState::Disabled);
|
|
||||||
|
|
||||||
auto id = Processor::current_id().as_u32();
|
bool try_lock_interrupts_disabled();
|
||||||
|
|
||||||
ProcessorID::value_type expected = PROCESSOR_NONE.as_u32();
|
void unlock(InterruptState state);
|
||||||
while (!m_locker.compare_exchange(expected, id, BAN::MemoryOrder::memory_order_acq_rel))
|
|
||||||
{
|
|
||||||
if (expected == id)
|
|
||||||
break;
|
|
||||||
Processor::pause();
|
|
||||||
expected = PROCESSOR_NONE.as_u32();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_lock_depth++;
|
|
||||||
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
void unlock(InterruptState state)
|
|
||||||
{
|
|
||||||
ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled);
|
|
||||||
ASSERT(current_processor_has_lock());
|
|
||||||
ASSERT(m_lock_depth > 0);
|
|
||||||
if (--m_lock_depth == 0)
|
|
||||||
m_locker.store(PROCESSOR_NONE.as_u32(), BAN::MemoryOrder::memory_order_release);
|
|
||||||
Processor::set_interrupt_state(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t lock_depth() const { return m_lock_depth; }
|
uint32_t lock_depth() const { return m_lock_depth; }
|
||||||
|
|
||||||
|
|
|
@ -377,6 +377,9 @@ namespace Kernel::ACPI::AML
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: WHY TF IS THIS USING OVER 1 KiB of stack
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wstack-usage="
|
||||||
static BAN::ErrorOr<Node> parse_logical_op(ParseContext& context)
|
static BAN::ErrorOr<Node> parse_logical_op(ParseContext& context)
|
||||||
{
|
{
|
||||||
dprintln_if(AML_DUMP_FUNCTION_CALLS, "parse_logical_op");
|
dprintln_if(AML_DUMP_FUNCTION_CALLS, "parse_logical_op");
|
||||||
|
@ -467,6 +470,7 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
static BAN::ErrorOr<Node> parse_index_op(ParseContext& context);
|
static BAN::ErrorOr<Node> parse_index_op(ParseContext& context);
|
||||||
|
|
||||||
|
@ -1537,6 +1541,9 @@ namespace Kernel::ACPI::AML
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: WHY TF IS THIS USING OVER 1 KiB of stack
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wstack-usage="
|
||||||
static BAN::ErrorOr<Node> parse_explicit_conversion(ParseContext& context)
|
static BAN::ErrorOr<Node> parse_explicit_conversion(ParseContext& context)
|
||||||
{
|
{
|
||||||
dprintln_if(AML_DUMP_FUNCTION_CALLS, "parse_explicit_conversion");
|
dprintln_if(AML_DUMP_FUNCTION_CALLS, "parse_explicit_conversion");
|
||||||
|
@ -1689,6 +1696,7 @@ namespace Kernel::ACPI::AML
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
static BAN::ErrorOr<Node> parse_to_string_op(ParseContext& context)
|
static BAN::ErrorOr<Node> parse_to_string_op(ParseContext& context)
|
||||||
{
|
{
|
||||||
|
@ -2750,7 +2758,9 @@ namespace Kernel::ACPI::AML
|
||||||
return method_call(scope, method, BAN::move(args));
|
return method_call(scope, method, BAN::move(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: WHY TF IS THIS USING OVER 2 KiB of stack
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wstack-usage="
|
||||||
BAN::ErrorOr<Node> parse_node(ParseContext& context, bool return_ref)
|
BAN::ErrorOr<Node> parse_node(ParseContext& context, bool return_ref)
|
||||||
{
|
{
|
||||||
if (context.aml_data.empty())
|
if (context.aml_data.empty())
|
||||||
|
@ -2961,13 +2971,11 @@ namespace Kernel::ACPI::AML
|
||||||
reference.as.reference->ref_count++;
|
reference.as.reference->ref_count++;
|
||||||
return reference;
|
return reference;
|
||||||
}
|
}
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
// FIXME: WHY TF IS THIS USING ALMOST 2 KiB of stack
|
// FIXME: WHY TF IS THIS USING ALMOST 2 KiB of stack
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#if defined(__GNUC__) && !defined(__clang__)
|
|
||||||
#pragma GCC diagnostic ignored "-Wstack-usage="
|
#pragma GCC diagnostic ignored "-Wstack-usage="
|
||||||
#endif
|
|
||||||
|
|
||||||
BAN::ErrorOr<ExecutionFlowResult> parse_node_or_execution_flow(ParseContext& context)
|
BAN::ErrorOr<ExecutionFlowResult> parse_node_or_execution_flow(ParseContext& context)
|
||||||
{
|
{
|
||||||
if (context.aml_data.empty())
|
if (context.aml_data.empty())
|
||||||
|
@ -3103,7 +3111,6 @@ namespace Kernel::ACPI::AML
|
||||||
.elem2 = BAN::move(node)
|
.elem2 = BAN::move(node)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
BAN::ErrorOr<NameString> NameString::from_string(BAN::StringView name)
|
BAN::ErrorOr<NameString> NameString::from_string(BAN::StringView name)
|
||||||
|
|
|
@ -52,4 +52,59 @@ namespace Kernel
|
||||||
Processor::set_interrupt_state(state);
|
Processor::set_interrupt_state(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InterruptState RecursiveSpinLock::lock()
|
||||||
|
{
|
||||||
|
auto state = Processor::get_interrupt_state();
|
||||||
|
Processor::set_interrupt_state(InterruptState::Disabled);
|
||||||
|
|
||||||
|
auto id = Processor::current_id().as_u32();
|
||||||
|
|
||||||
|
ProcessorID::value_type expected = PROCESSOR_NONE.as_u32();
|
||||||
|
while (!m_locker.compare_exchange(expected, id, BAN::MemoryOrder::memory_order_acq_rel))
|
||||||
|
{
|
||||||
|
if (expected == id)
|
||||||
|
break;
|
||||||
|
Processor::pause();
|
||||||
|
expected = PROCESSOR_NONE.as_u32();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_lock_depth++;
|
||||||
|
|
||||||
|
if (Thread::current_tid())
|
||||||
|
Thread::current().add_spinlock();
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RecursiveSpinLock::try_lock_interrupts_disabled()
|
||||||
|
{
|
||||||
|
ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled);
|
||||||
|
|
||||||
|
auto id = Processor::current_id().as_u32();
|
||||||
|
|
||||||
|
ProcessorID::value_type expected = PROCESSOR_NONE.as_u32();
|
||||||
|
if (!m_locker.compare_exchange(expected, id, BAN::MemoryOrder::memory_order_acq_rel))
|
||||||
|
if (expected != id)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_lock_depth++;
|
||||||
|
|
||||||
|
if (Thread::current_tid())
|
||||||
|
Thread::current().add_spinlock();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecursiveSpinLock::unlock(InterruptState state)
|
||||||
|
{
|
||||||
|
ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled);
|
||||||
|
ASSERT(current_processor_has_lock());
|
||||||
|
ASSERT(m_lock_depth > 0);
|
||||||
|
if (--m_lock_depth == 0)
|
||||||
|
m_locker.store(PROCESSOR_NONE.as_u32(), BAN::MemoryOrder::memory_order_release);
|
||||||
|
if (Thread::current_tid())
|
||||||
|
Thread::current().remove_spinlock();
|
||||||
|
Processor::set_interrupt_state(state);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue