Compare commits

..

2 Commits

Author SHA1 Message Date
0bdbffe0ca
Spinlock+LockedValue: Add try_lock() methods
All checks were successful
continuous-integration/drone/push Build is passing
For when you want to lock a resource if possible but not get blocked if it is locked by another thread.
2022-12-18 20:37:26 +01:00
283e641ece
Spinlock+LockedValue: Remove init() functions
Let's set the default (unlocked) value of Spinlock's underlying atomic to 0, so even if the constructor is not called it stays like that.
2022-12-18 20:36:15 +01:00
4 changed files with 34 additions and 27 deletions

View File

@ -21,8 +21,6 @@ namespace KernelVM
{ {
void init() void init()
{ {
g_kernelvm_bitmap.init();
auto kernelvm_bitmap = g_kernelvm_bitmap.lock(); auto kernelvm_bitmap = g_kernelvm_bitmap.lock();
kernelvm_bitmap->initialize(bitmap_memory, sizeof(bitmap_memory)); kernelvm_bitmap->initialize(bitmap_memory, sizeof(bitmap_memory));
kernelvm_bitmap->clear(false); kernelvm_bitmap->clear(false);

View File

@ -53,8 +53,6 @@ namespace MemoryManager
MemoryMapIterator iter; MemoryMapIterator iter;
MemoryMapEntry entry; MemoryMapEntry entry;
g_frame_bitmap.init();
const auto largest_free_entry = iter.largest_free(); const auto largest_free_entry = iter.largest_free();
expect(largest_free_entry.is_free(), "We were given a largest free memory region that isn't even free!"); expect(largest_free_entry.is_free(), "We were given a largest free memory region that isn't even free!");

View File

@ -4,18 +4,24 @@
void Spinlock::lock() void Spinlock::lock()
{ {
int expected = -1; int expected = 0;
while (!m_lock.compare_exchange_strong(expected, 0)) while (!m_lock.compare_exchange_strong(expected, 1))
{ {
expected = -1; expected = 0;
CPU::pause(); CPU::pause();
} }
} }
void Spinlock::unlock() bool Spinlock::try_lock()
{ {
int expected = 0; int expected = 0;
if (!m_lock.compare_exchange_strong(expected, -1)) return m_lock.compare_exchange_strong(expected, 1);
}
void Spinlock::unlock()
{
int expected = 1;
if (!m_lock.compare_exchange_strong(expected, 0))
{ {
kwarnln("Spinlock::unlock() called on an unlocked lock with value %d", expected); kwarnln("Spinlock::unlock() called on an unlocked lock with value %d", expected);
} }

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <luna/Atomic.h> #include <luna/Atomic.h>
#include <luna/Option.h>
class Spinlock class Spinlock
{ {
@ -7,37 +8,41 @@ class Spinlock
void lock(); void lock();
void unlock(); void unlock();
bool try_lock();
bool is_locked() const bool is_locked() const
{ {
return m_lock.load() != -1; return m_lock.load() != 0;
}
// Call this before use if the Spinlock is a global variable.
void init()
{
m_lock = -1;
} }
private: private:
Atomic<int> m_lock{-1}; Atomic<int> m_lock{0};
}; };
template <typename T> class LockedValue template <typename T> class LockedValue
{ {
struct LockedValueGuard struct LockedValueGuard
{ {
LockedValueGuard(LockedValue& value_ref) : m_value_ref(value_ref) LockedValueGuard(LockedValue& value_ref) : m_value_ref(&value_ref)
{ {
} }
LockedValueGuard(const LockedValueGuard& other) = delete;
LockedValueGuard(LockedValueGuard&& other)
{
m_value_ref = other.m_value_ref;
other.m_value_ref = nullptr;
}
~LockedValueGuard() ~LockedValueGuard()
{ {
m_value_ref.m_lock.unlock(); if (m_value_ref) m_value_ref->m_lock.unlock();
} }
T& ref() T& ref()
{ {
return m_value_ref.m_value; expect(m_value_ref, "LockedValueGuard::ref() called on a moved LockedValueGuard");
return m_value_ref->m_value;
} }
void set(const T& other) void set(const T& other)
@ -56,7 +61,7 @@ template <typename T> class LockedValue
} }
private: private:
LockedValue& m_value_ref; LockedValue* m_value_ref;
}; };
public: public:
@ -68,18 +73,18 @@ template <typename T> class LockedValue
{ {
} }
// Call this before use if the LockedValue is a global variable.
void init()
{
m_lock.init();
}
LockedValueGuard lock() LockedValueGuard lock()
{ {
m_lock.lock(); m_lock.lock();
return {*this}; return {*this};
} }
Option<LockedValueGuard> try_lock()
{
if (m_lock.try_lock()) { return {*this}; }
return {};
}
private: private:
T m_value; T m_value;
Spinlock m_lock; Spinlock m_lock;