kernel, luna: Move Spinlock.h to luna

This commit is contained in:
apio 2023-02-14 20:05:00 +01:00
parent c422d11682
commit 9274ad0404
Signed by: apio
GPG Key ID: B8A7D06E42258954
2 changed files with 0 additions and 192 deletions

View File

@ -1,53 +0,0 @@
#include "thread/Spinlock.h"
#include "Log.h"
#include "arch/CPU.h"
void Spinlock::lock()
{
int expected = 0;
while (!m_lock.compare_exchange_strong(expected, 1))
{
expected = 0;
CPU::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))
{
kwarnln("Spinlock::unlock() called on an unlocked lock with value %d", expected);
}
}
ScopeLock::ScopeLock(Spinlock& lock) : m_lock(lock)
{
m_lock.lock();
}
ScopeLock::~ScopeLock()
{
m_lock.unlock();
}
const u32 RETRIES = 5000000;
SafeScopeLock::SafeScopeLock(Spinlock& lock) : m_lock(lock)
{
u32 tries_left = RETRIES;
while (!lock.try_lock() && --tries_left) { CPU::pause(); }
if (tries_left) m_success = true;
}
SafeScopeLock::~SafeScopeLock()
{
if (m_success) m_lock.unlock();
}

View File

@ -1,139 +0,0 @@
#pragma once
#include "Log.h"
#include "arch/CPU.h"
#include <luna/Atomic.h>
#include <luna/Option.h>
class Spinlock
{
public:
void lock();
void unlock();
bool try_lock();
bool is_locked() const
{
return m_lock.load() != 0;
}
private:
Atomic<int> m_lock { 0 };
};
class ScopeLock
{
public:
ScopeLock(Spinlock& lock);
~ScopeLock();
ScopeLock(const ScopeLock&) = delete;
ScopeLock(ScopeLock&&) = delete;
private:
Spinlock& m_lock;
};
class SafeScopeLock
{
public:
SafeScopeLock(Spinlock& lock);
~SafeScopeLock();
SafeScopeLock(const SafeScopeLock&) = delete;
SafeScopeLock(SafeScopeLock&&) = delete;
bool did_succeed() const
{
return m_success;
}
private:
Spinlock& m_lock;
bool m_success { false };
};
template <typename T> class LockedValue
{
struct LockedValueGuard
{
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()
{
if (m_value_ref) m_value_ref->m_lock.unlock();
}
T& ref()
{
expect(m_value_ref, "LockedValueGuard::ref() called on a moved LockedValueGuard");
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)
{
}
#ifndef LOCKED_VALUE_DEBUG
LockedValueGuard lock()
{
m_lock.lock();
return { *this };
}
#else
LockedValueGuard lock()
{
if (m_lock.try_lock()) { return { *this }; }
kwarnln("Spinning on a locked LockedValue. This might lead to a deadlock...");
CPU::print_stack_trace();
m_lock.lock();
return { *this };
}
#endif
Option<LockedValueGuard> try_lock()
{
if (m_lock.try_lock()) { return { *this }; }
return {};
}
private:
T m_value;
Spinlock m_lock;
};