Luna/kernel/src/thread/Spinlock.h

86 lines
1.3 KiB
C
Raw Normal View History

#pragma once
#include <luna/Atomic.h>
class Spinlock
{
public:
void lock();
void unlock();
bool is_locked() const
{
return m_lock.load() != -1;
}
// Call this before use if the Spinlock is a global variable.
void init()
{
m_lock = -1;
}
private:
Atomic<int> m_lock{-1};
};
template <typename T> class LockedValue
{
struct LockedValueGuard
{
LockedValueGuard(LockedValue& value_ref) : m_value_ref(value_ref)
{
}
~LockedValueGuard()
{
m_value_ref.m_lock.unlock();
}
T& ref()
{
return m_value_ref.m_value;
}
void set(const T& other)
{
ref() = other;
}
T* operator->()
{
return &ref();
}
T& operator*()
{
return ref();
}
private:
LockedValue& m_value_ref;
};
public:
LockedValue() : m_value()
{
}
LockedValue(T value) : m_value(value)
{
}
// Call this before use if the LockedValue is a global variable.
void init()
{
m_lock.init();
}
LockedValueGuard lock()
{
m_lock.lock();
return {*this};
}
private:
T m_value;
Spinlock m_lock;
};