mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-24 15:13:57 +00:00
933a98f8fa
The scheduler is not allowed to take locks, so if that's happening, we want to make that clear instead of crashing with the more general "Interrupts disabled while trying to take Lock" error.
70 lines
1.6 KiB
C++
70 lines
1.6 KiB
C++
#include <Kernel/Lock.h>
|
|
|
|
void Lock::lock()
|
|
{
|
|
ASSERT(!Scheduler::is_active());
|
|
if (!are_interrupts_enabled()) {
|
|
kprintf("Interrupts disabled when trying to take Lock{%s}\n", m_name);
|
|
dump_backtrace();
|
|
hang();
|
|
}
|
|
for (;;) {
|
|
if (CAS(&m_lock, 1, 0) == 0) {
|
|
if (!m_holder || m_holder == current) {
|
|
m_holder = current;
|
|
++m_level;
|
|
memory_barrier();
|
|
m_lock = 0;
|
|
return;
|
|
}
|
|
m_lock = 0;
|
|
}
|
|
Scheduler::donate_to(m_holder, m_name);
|
|
}
|
|
}
|
|
|
|
void Lock::unlock()
|
|
{
|
|
for (;;) {
|
|
if (CAS(&m_lock, 1, 0) == 0) {
|
|
ASSERT(m_holder == current);
|
|
ASSERT(m_level);
|
|
--m_level;
|
|
if (m_level) {
|
|
memory_barrier();
|
|
m_lock = 0;
|
|
return;
|
|
}
|
|
m_holder = nullptr;
|
|
memory_barrier();
|
|
m_lock = 0;
|
|
return;
|
|
}
|
|
Scheduler::donate_to(m_holder, m_name);
|
|
}
|
|
}
|
|
|
|
bool Lock::unlock_if_locked()
|
|
{
|
|
for (;;) {
|
|
if (CAS(&m_lock, 1, 0) == 0) {
|
|
if (m_level == 0) {
|
|
memory_barrier();
|
|
m_lock = 0;
|
|
return false;
|
|
}
|
|
ASSERT(m_holder == current);
|
|
ASSERT(m_level);
|
|
--m_level;
|
|
if (m_level) {
|
|
memory_barrier();
|
|
m_lock = 0;
|
|
return false;
|
|
}
|
|
m_holder = nullptr;
|
|
memory_barrier();
|
|
m_lock = 0;
|
|
return true;
|
|
}
|
|
}
|
|
}
|