diff --git a/mesosphere/include/mesosphere/core/KLinkedList.hpp b/mesosphere/include/mesosphere/core/KLinkedList.hpp index 587d6fa70..0326187eb 100644 --- a/mesosphere/include/mesosphere/core/KLinkedList.hpp +++ b/mesosphere/include/mesosphere/core/KLinkedList.hpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include namespace mesosphere diff --git a/mesosphere/include/mesosphere/core/KSynchronizationObject.hpp b/mesosphere/include/mesosphere/core/KSynchronizationObject.hpp new file mode 100644 index 000000000..1e4f420aa --- /dev/null +++ b/mesosphere/include/mesosphere/core/KSynchronizationObject.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include +#include + +namespace mesosphere +{ + +class KSynchronizationObject : public KAutoObject { + public: + + MESOSPHERE_AUTO_OBJECT_TRAITS(AutoObject, SynchronizationObject); + + virtual ~KSynchronizationObject(); + virtual bool IsSignaled() const = 0; + + void Signal(); // Note: Signal() with !IsSignaled() is no-op + + KLinkedList::const_iterator AddWaiter(KThread &thread); + void RemoveWaiter(KLinkedList::const_iterator it); + + private: + KLinkedList waiters{}; +}; + +} diff --git a/mesosphere/include/mesosphere/core/types.hpp b/mesosphere/include/mesosphere/core/types.hpp index adb4a0dbe..2554e994d 100644 --- a/mesosphere/include/mesosphere/core/types.hpp +++ b/mesosphere/include/mesosphere/core/types.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #define MAX_CORES 4 @@ -10,6 +11,8 @@ namespace mesosphere { +using namespace std::chrono_literals; + using ushort = unsigned short; using uint = unsigned int; using ulong = unsigned long; diff --git a/mesosphere/include/mesosphere/threading/KThread.hpp b/mesosphere/include/mesosphere/threading/KThread.hpp index 8ccc8f305..d54412f5a 100644 --- a/mesosphere/include/mesosphere/threading/KThread.hpp +++ b/mesosphere/include/mesosphere/threading/KThread.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -206,6 +207,9 @@ class KThread final : /// Takes effect immediately void CancelKernelSync(Result res); + /// Takes effect when critical section is left + void HandleSyncObjectSignaled(KSynchronizationObject *syncObj); + constexpr size_t GetNumberOfKMutexWaiters() const { return numKernelMutexWaiters; } constexpr uiptr GetWantedMutex() const { return wantedMutex; } void SetWantedMutex(uiptr mtx) { wantedMutex = mtx; } @@ -244,8 +248,8 @@ private: MutexWaitList mutexWaitList{}; size_t numKernelMutexWaiters = 0; - Handle syncResultHandle{}; - Result syncResult = ResultSuccess(); + KSynchronizationObject *signaledSyncObject = nullptr; + Result syncResult = ResultSuccess{}; u64 lastScheduledTime = 0; }; diff --git a/mesosphere/source/core/KSynchronizationObject.cpp b/mesosphere/source/core/KSynchronizationObject.cpp new file mode 100644 index 000000000..c42ff4f83 --- /dev/null +++ b/mesosphere/source/core/KSynchronizationObject.cpp @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include + +#include + +namespace mesosphere +{ + +KSynchronizationObject::~KSynchronizationObject() +{ +} + +void KSynchronizationObject::Signal() +{ + std::lock_guard criticalSection{KScheduler::GetCriticalSection()}; + + if (IsSignaled()) { + for (auto &&waiter : waiters) { + waiter->HandleSyncObjectSignaled(this); + } + } +} + +KLinkedList::const_iterator KSynchronizationObject::AddWaiter(KThread &thread) +{ + return waiters.insert(waiters.end(), &thread); +} + +void KSynchronizationObject::RemoveWaiter(KLinkedList::const_iterator it) +{ + waiters.erase(it); +} + +} diff --git a/mesosphere/source/threading/KThread.cpp b/mesosphere/source/threading/KThread.cpp index 7cf45f020..8d4e51bc5 100644 --- a/mesosphere/source/threading/KThread.cpp +++ b/mesosphere/source/threading/KThread.cpp @@ -120,6 +120,15 @@ void KThread::CancelKernelSync(Result res) CancelKernelSync(); } +void KThread::HandleSyncObjectSignaled(KSynchronizationObject *syncObj) +{ + if (GetSchedulingStatus() == SchedulingStatus::Paused) { + signaledSyncObject = syncObj; + syncResult = ResultSuccess{}; + Reschedule(SchedulingStatus::Running); + } +} + void KThread::AddToMutexWaitList(KThread &thread) { // TODO: check&increment numKernelMutexWaiters