mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-23 04:41:12 +00:00
Implement KCriticalSection (mostly)
This commit is contained in:
parent
4238d2e97f
commit
0fb40d1ef5
12 changed files with 115 additions and 21 deletions
|
@ -45,7 +45,7 @@ class KInterruptMaskGuard final {
|
||||||
KInterruptMaskGuard &operator=(KInterruptMaskGuard &&) = delete;
|
KInterruptMaskGuard &operator=(KInterruptMaskGuard &&) = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FlagsType flags;
|
FlagsType flags = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ inline void IncrementThreadInterruptBottomHalfLockCount(KThread &thread);
|
||||||
inline void DecrementThreadInterruptBottomHalfLockCount(KThread &thread);
|
inline void DecrementThreadInterruptBottomHalfLockCount(KThread &thread);
|
||||||
|
|
||||||
template<bool disableInterrupts = false>
|
template<bool disableInterrupts = false>
|
||||||
class KInterruptSpinLock final : public KSpinLock {
|
class KInterruptSpinLock : public KSpinLock {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
bool try_lock()
|
bool try_lock()
|
||||||
|
@ -48,7 +48,7 @@ class KInterruptSpinLock final : public KSpinLock {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
class KInterruptSpinLock<true> final : public KSpinLock {
|
class KInterruptSpinLock<true> : public KSpinLock {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
bool try_lock()
|
bool try_lock()
|
||||||
|
@ -80,7 +80,7 @@ class KInterruptSpinLock<true> final : public KSpinLock {
|
||||||
KInterruptSpinLock &operator=(KInterruptSpinLock &&) = delete;
|
KInterruptSpinLock &operator=(KInterruptSpinLock &&) = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typename KInterruptMaskGuard::FlagsType flags;
|
typename KInterruptMaskGuard::FlagsType flags = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
26
mesosphere/include/mesosphere/threading/KCriticalSection.hpp
Normal file
26
mesosphere/include/mesosphere/threading/KCriticalSection.hpp
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mesosphere/interrupts/KInterruptSpinLock.hpp>
|
||||||
|
|
||||||
|
namespace mesosphere
|
||||||
|
{
|
||||||
|
|
||||||
|
class KCriticalSection final : public KInterruptSpinLock<false> {
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool try_lock();
|
||||||
|
void lock();
|
||||||
|
void unlock();
|
||||||
|
|
||||||
|
KCriticalSection() = default;
|
||||||
|
KCriticalSection(const KCriticalSection &) = delete;
|
||||||
|
KCriticalSection(KCriticalSection &&) = delete;
|
||||||
|
KCriticalSection &operator=(const KCriticalSection &) = delete;
|
||||||
|
KCriticalSection &operator=(KCriticalSection &&) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
KThread *lockingThread = nullptr;
|
||||||
|
ulong lockCount = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -4,14 +4,12 @@
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <mesosphere/core/util.hpp>
|
#include <mesosphere/core/util.hpp>
|
||||||
#include <mesosphere/threading/KMultiLevelQueue.hpp>
|
#include <mesosphere/threading/KMultiLevelQueue.hpp>
|
||||||
|
#include <mesosphere/threading/KCriticalSection.hpp>
|
||||||
#include <mesosphere/threading/KThread.hpp>
|
#include <mesosphere/threading/KThread.hpp>
|
||||||
|
|
||||||
namespace mesosphere
|
namespace mesosphere
|
||||||
{
|
{
|
||||||
|
|
||||||
//TODO
|
|
||||||
struct KCriticalSection { void lock() {} void unlock() {} bool try_lock() {return true;} };
|
|
||||||
|
|
||||||
class KScheduler {
|
class KScheduler {
|
||||||
public:
|
public:
|
||||||
class Global {
|
class Global {
|
||||||
|
@ -40,6 +38,8 @@ class KScheduler {
|
||||||
|
|
||||||
static constexpr uint minRegularPriority = 2;
|
static constexpr uint minRegularPriority = 2;
|
||||||
private:
|
private:
|
||||||
|
friend class KScheduler;
|
||||||
|
|
||||||
static void TransferThreadToCore(KThread &thread, int coreId);
|
static void TransferThreadToCore(KThread &thread, int coreId);
|
||||||
static void AskForReselectionOrMarkRedundant(KThread *currentThread, KThread *winner);
|
static void AskForReselectionOrMarkRedundant(KThread *currentThread, KThread *winner);
|
||||||
|
|
||||||
|
@ -91,6 +91,11 @@ class KScheduler {
|
||||||
static void YieldCurrentThreadAndBalanceLoad();
|
static void YieldCurrentThreadAndBalanceLoad();
|
||||||
static void YieldCurrentThreadAndWaitForLoadBalancing();
|
static void YieldCurrentThreadAndWaitForLoadBalancing();
|
||||||
|
|
||||||
|
static void HandleCriticalSectionLeave();
|
||||||
|
friend void SchedulerHandleCriticalSectionLeave()
|
||||||
|
{
|
||||||
|
HandleCriticalSectionLeave();
|
||||||
|
}
|
||||||
|
|
||||||
void ForceContextSwitch() {}
|
void ForceContextSwitch() {}
|
||||||
void ForceContextSwitchAfterIrq() {}
|
void ForceContextSwitchAfterIrq() {}
|
||||||
|
@ -99,6 +104,7 @@ class KScheduler {
|
||||||
|
|
||||||
constexpr ulong GetIdleSelectionCount() const { return idleSelectionCount; }
|
constexpr ulong GetIdleSelectionCount() const { return idleSelectionCount; }
|
||||||
constexpr bool IsActive() const { return /*isActive */ true; } // TODO
|
constexpr bool IsActive() const { return /*isActive */ true; } // TODO
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool hasContextSwitchStartedAfterIrq;
|
bool hasContextSwitchStartedAfterIrq;
|
||||||
bool isActive;
|
bool isActive;
|
||||||
|
@ -128,11 +134,4 @@ class KScheduler {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Convenience
|
|
||||||
|
|
||||||
class KScopedCriticalSection {
|
|
||||||
private:
|
|
||||||
std::scoped_lock<KCriticalSection> lk{KScheduler::GetCriticalSection()};
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mesosphere/threading/KScheduler.hpp>
|
||||||
|
|
||||||
|
namespace mesosphere
|
||||||
|
{
|
||||||
|
|
||||||
|
class KScopedCriticalSection final {
|
||||||
|
private:
|
||||||
|
std::scoped_lock<KCriticalSection> lk{KScheduler::GetCriticalSection()};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
#include <mesosphere/core/KSynchronizationObject.hpp>
|
#include <mesosphere/core/KSynchronizationObject.hpp>
|
||||||
#include <mesosphere/core/Result.hpp>
|
#include <mesosphere/core/Result.hpp>
|
||||||
#include <mesosphere/threading/KScheduler.hpp>
|
#include <mesosphere/threading/KScopedCriticalSection.hpp>
|
||||||
#include <mesosphere/threading/KThread.hpp>
|
#include <mesosphere/threading/KThread.hpp>
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include <mesosphere/processes/KWritableEvent.hpp>
|
#include <mesosphere/processes/KWritableEvent.hpp>
|
||||||
#include <mesosphere/processes/KReadableEvent.hpp>
|
#include <mesosphere/processes/KReadableEvent.hpp>
|
||||||
#include <mesosphere/processes/KEvent.hpp>
|
#include <mesosphere/processes/KEvent.hpp>
|
||||||
#include <mesosphere/threading/KScheduler.hpp>
|
#include <mesosphere/threading/KScopedCriticalSection.hpp>
|
||||||
|
|
||||||
namespace mesosphere
|
namespace mesosphere
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <mesosphere/threading/KConditionVariable.hpp>
|
#include <mesosphere/threading/KConditionVariable.hpp>
|
||||||
#include <mesosphere/threading/KScheduler.hpp>
|
#include <mesosphere/threading/KScopedCriticalSection.hpp>
|
||||||
#include <mesosphere/core/KCoreContext.hpp>
|
#include <mesosphere/core/KCoreContext.hpp>
|
||||||
|
|
||||||
namespace mesosphere
|
namespace mesosphere
|
||||||
|
|
45
mesosphere/source/threading/KCriticalSection.cpp
Normal file
45
mesosphere/source/threading/KCriticalSection.cpp
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#include <mesosphere/threading/KCriticalSection.hpp>
|
||||||
|
#include <mesosphere/threading/KScheduler.hpp>
|
||||||
|
#include <mesosphere/core/KCoreContext.hpp>
|
||||||
|
|
||||||
|
namespace mesosphere
|
||||||
|
{
|
||||||
|
|
||||||
|
bool KCriticalSection::try_lock()
|
||||||
|
{
|
||||||
|
KThread *curThread = KCoreContext::GetCurrentInstance().GetCurrentThread();
|
||||||
|
if (curThread == lockingThread) {
|
||||||
|
++lockCount;
|
||||||
|
return true;
|
||||||
|
} else if (KInterruptSpinLock<false>::try_lock()) {
|
||||||
|
lockingThread = curThread;
|
||||||
|
lockCount = 1;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KCriticalSection::lock()
|
||||||
|
{
|
||||||
|
KThread *curThread = KCoreContext::GetCurrentInstance().GetCurrentThread();
|
||||||
|
if (curThread == lockingThread) {
|
||||||
|
++lockCount;
|
||||||
|
} else {
|
||||||
|
KInterruptSpinLock<false>::lock();
|
||||||
|
lockingThread = curThread;
|
||||||
|
lockCount = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KCriticalSection::unlock()
|
||||||
|
{
|
||||||
|
if (--lockCount == 0) {
|
||||||
|
lockingThread = nullptr;
|
||||||
|
KScheduler::HandleCriticalSectionLeave();
|
||||||
|
} else {
|
||||||
|
KInterruptSpinLock<false>::unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
#include <mesosphere/threading/KMutex.hpp>
|
#include <mesosphere/threading/KMutex.hpp>
|
||||||
#include <mesosphere/threading/KThread.hpp>
|
#include <mesosphere/threading/KThread.hpp>
|
||||||
#include <mesosphere/threading/KScheduler.hpp>
|
#include <mesosphere/threading/KScopedCriticalSection.hpp>
|
||||||
|
|
||||||
namespace mesosphere
|
namespace mesosphere
|
||||||
{
|
{
|
||||||
|
|
|
@ -341,4 +341,15 @@ void KScheduler::YieldCurrentThreadAndWaitForLoadBalancing()
|
||||||
cctx.GetScheduler()->DoYieldOperation(Global::YieldThreadAndWaitForLoadBalancing, *cctx.GetCurrentThread());
|
cctx.GetScheduler()->DoYieldOperation(Global::YieldThreadAndWaitForLoadBalancing, *cctx.GetCurrentThread());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KScheduler::HandleCriticalSectionLeave()
|
||||||
|
{
|
||||||
|
if (KScheduler::Global::reselectionRequired) {
|
||||||
|
KScheduler::Global::SelectThreads();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::atomic_thread_fence(std::memory_order_seq_cst);
|
||||||
|
|
||||||
|
// TODO: check which cores needs ctx switches, sent interrupts and/or ctx switch ourselves
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include <mesosphere/threading/KThread.hpp>
|
#include <mesosphere/threading/KThread.hpp>
|
||||||
#include <mesosphere/threading/KScheduler.hpp>
|
#include <mesosphere/threading/KScopedCriticalSection.hpp>
|
||||||
|
|
||||||
namespace mesosphere
|
namespace mesosphere
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue