All checks were successful
continuous-integration/drone/push Build is passing
OwnedPtr, SharedPtr: Add operator bool Option, Result: Make try_move_value() non-const since it modifies the Option kernel: Switch to a stack we control for the main task as soon as we leave early boot Heap: Fix GPF caused when making many small allocations Heap: Avoid accessing a block after it's potentially deleted luna: Skip UBSAN.cpp in CMakeLists as that's not implemented yet luna: Use spinlocks in the heap implementation kernel, luna: Move Spinlock.h to luna Option: Use __builtin_launder to ensure that the compiler doesn't label this as UB SharedPtr: Implement make_shared using adopt_shared SharedPtr: Delete ptr on failure in all adopt_shared* functions
59 lines
1.0 KiB
C++
59 lines
1.0 KiB
C++
#include <luna/DebugLog.h>
|
|
#include <luna/Spinlock.h>
|
|
|
|
#ifdef ARCH_X86_64
|
|
#define pause() asm volatile("pause")
|
|
#else
|
|
#error "Unsupported architecture"
|
|
#endif
|
|
|
|
void Spinlock::lock()
|
|
{
|
|
int expected = 0;
|
|
while (!m_lock.compare_exchange_strong(expected, 1))
|
|
{
|
|
expected = 0;
|
|
pause();
|
|
}
|
|
}
|
|
|
|
bool Spinlock::try_lock()
|
|
{
|
|
int expected = 0;
|
|
return m_lock.compare_exchange_strong(expected, 1);
|
|
}
|
|
|
|
void Spinlock::unlock()
|
|
{
|
|
int expected = 1;
|
|
if (!m_lock.compare_exchange_strong(expected, 0))
|
|
{
|
|
dbgln("Spinlock::unlock() called on an unlocked lock with value %d", expected);
|
|
}
|
|
}
|
|
|
|
ScopeLock::ScopeLock(Spinlock& lock) : m_lock(lock)
|
|
{
|
|
m_lock.lock();
|
|
}
|
|
|
|
ScopeLock::~ScopeLock()
|
|
{
|
|
if (!m_taken_over) m_lock.unlock();
|
|
}
|
|
|
|
const u32 RETRIES = 5000000;
|
|
|
|
SafeScopeLock::SafeScopeLock(Spinlock& lock) : m_lock(lock)
|
|
{
|
|
u32 tries_left = RETRIES;
|
|
while (!lock.try_lock() && --tries_left) { pause(); }
|
|
|
|
if (tries_left) m_success = true;
|
|
}
|
|
|
|
SafeScopeLock::~SafeScopeLock()
|
|
{
|
|
if (m_success) m_lock.unlock();
|
|
}
|