From e57203a7d4c32d21ae6d2b3da99ba7ace892c20d Mon Sep 17 00:00:00 2001 From: TuxSH Date: Sun, 4 Nov 2018 22:13:53 +0100 Subject: [PATCH] Implement WaitSynchronization --- mesosphere/include/mesosphere/core/Result.hpp | 2 +- .../mesosphere/interfaces/IAlarmable.hpp | 4 +- .../include/mesosphere/threading/KThread.hpp | 11 ++- mesosphere/source/threading/KThread.cpp | 69 ++++++++++++++++++- 4 files changed, 81 insertions(+), 5 deletions(-) diff --git a/mesosphere/include/mesosphere/core/Result.hpp b/mesosphere/include/mesosphere/core/Result.hpp index a5ad0b60d..22b0a41a0 100644 --- a/mesosphere/include/mesosphere/core/Result.hpp +++ b/mesosphere/include/mesosphere/core/Result.hpp @@ -100,7 +100,7 @@ class ResultError : public ResultBase> { DEFINE_RESULT(Kernel, InvalidCapabilityDescriptor, 14); DEFINE_RESULT(Kernel, NotImplemented, 33); -DEFINE_RESULT(Kernel, ThreadTerminated, 59); +DEFINE_RESULT(Kernel, ThreadTerminating, 59); DEFINE_RESULT(Kernel, OutOfDebugEvents, 70); diff --git a/mesosphere/include/mesosphere/interfaces/IAlarmable.hpp b/mesosphere/include/mesosphere/interfaces/IAlarmable.hpp index dae8b181f..1aca58472 100644 --- a/mesosphere/include/mesosphere/interfaces/IAlarmable.hpp +++ b/mesosphere/include/mesosphere/interfaces/IAlarmable.hpp @@ -31,13 +31,13 @@ class IAlarmable : public AlarmableSetBaseHook { template void SetAlarmTime(const std::chrono::time_point &alarmTime) { - SetAlarmTime(alarmTime); + SetAlarmTimeImpl(alarmTime); } template void SetAlarmIn(const std::chrono::duration &alarmTimeOffset) { - SetAlarmTime(KSystemClock::now() + alarmTimeOffset); + SetAlarmTimeImpl(KSystemClock::now() + alarmTimeOffset); } void ClearAlarm(); diff --git a/mesosphere/include/mesosphere/threading/KThread.hpp b/mesosphere/include/mesosphere/threading/KThread.hpp index d54412f5a..293adfbf0 100644 --- a/mesosphere/include/mesosphere/threading/KThread.hpp +++ b/mesosphere/include/mesosphere/threading/KThread.hpp @@ -210,6 +210,12 @@ class KThread final : /// Takes effect when critical section is left void HandleSyncObjectSignaled(KSynchronizationObject *syncObj); + template + Result WaitSynchronization(int &outId, KSynchronizationObject **syncObjs, int numSyncObjs, const std::chrono::time_point &timeoutTime) + { + return WaitSynchronizationImpl(outId, syncObjs, numSyncObjs, timeoutTime); + } + constexpr size_t GetNumberOfKMutexWaiters() const { return numKernelMutexWaiters; } constexpr uiptr GetWantedMutex() const { return wantedMutex; } void SetWantedMutex(uiptr mtx) { wantedMutex = mtx; } @@ -224,6 +230,8 @@ class KThread final : id(id), basePriority(priority), priority(priority), currentCoreId(0), affinityMask(15) {}; private: + Result WaitSynchronizationImpl(int &outId, KSynchronizationObject **syncObjs, int numSyncObjs, const KSystemClock::time_point &timeoutTime); + void AddToMutexWaitList(KThread &thread); MutexWaitList::iterator RemoveFromMutexWaitList(MutexWaitList::const_iterator it); void RemoveFromMutexWaitList(const KThread &t); @@ -242,7 +250,8 @@ private: uint basePriority = 64, priority = 64; int currentCoreId = -1; ulong affinityMask = 0; - + bool cancelled = false; + bool isWaitingSync = false; uiptr wantedMutex = 0; KThread *wantedMutexOwner = nullptr; MutexWaitList mutexWaitList{}; diff --git a/mesosphere/source/threading/KThread.cpp b/mesosphere/source/threading/KThread.cpp index 8d4e51bc5..18f98cf01 100644 --- a/mesosphere/source/threading/KThread.cpp +++ b/mesosphere/source/threading/KThread.cpp @@ -32,7 +32,8 @@ void KThread::AdjustScheduling(ushort oldMaskFull) void KThread::Reschedule(KThread::SchedulingStatus newStatus) { - std::lock_guard criticalSection{KScheduler::GetCriticalSection()}; + //std::lock_guard criticalSection{KScheduler::GetCriticalSection()}; + // TODO check the above ^ AdjustScheduling(SetSchedulingStatusField(newStatus)); } @@ -129,6 +130,72 @@ void KThread::HandleSyncObjectSignaled(KSynchronizationObject *syncObj) } } +Result KThread::WaitSynchronizationImpl(int &outId, KSynchronizationObject **syncObjs, int numSyncObjs, const KSystemClock::time_point &timeoutTime) +{ + KLinkedList::const_iterator nodes[numSyncObjs]; + + outId = -1; + { + std::lock_guard criticalSection{KScheduler::GetCriticalSection()}; + + // Try to find an already signaled object. + if (numSyncObjs >= 1) { + KSynchronizationObject **readyFound = std::find_if( + syncObjs, + syncObjs + numSyncObjs, + [](KSynchronizationObject *obj) { + return obj->IsSignaled(); + } + ); + + outId = readyFound - syncObjs >= numSyncObjs ? -1 : readyFound - syncObjs; + } + + if (timeoutTime == KSystemClock::time_point{} && outId == -1) { + return ResultKernelTimedOut{}; + } + if (IsDying()) { + return ResultKernelThreadTerminating{}; + } + if (cancelled) { + return ResultKernelCancelled{}; + } + + for (int i = 0; i < numSyncObjs; i++) { + nodes[i] = syncObjs[i]->AddWaiter(*this); + } + + isWaitingSync = true; + signaledSyncObject = nullptr; + syncResult = ResultKernelTimedOut{}; + + Reschedule(SchedulingStatus::Paused); + if (timeoutTime > KSystemClock::time_point{}) { + SetAlarmTime(timeoutTime); + } + } + + // Now waiting... + + { + std::lock_guard criticalSection{KScheduler::GetCriticalSection()}; + + isWaitingSync = false; + if (timeoutTime > KSystemClock::time_point{}) { + ClearAlarm(); + } + + for (int i = 0; i < numSyncObjs; i++) { + syncObjs[i]->RemoveWaiter(nodes[i]); + if (syncObjs[i] == signaledSyncObject) { + outId = i; + } + } + } + + return syncResult; +} + void KThread::AddToMutexWaitList(KThread &thread) { // TODO: check&increment numKernelMutexWaiters