Implement WaitSynchronization

This commit is contained in:
TuxSH 2018-11-04 22:13:53 +01:00 committed by Michael Scire
parent 7fde5fbe40
commit e57203a7d4
4 changed files with 81 additions and 5 deletions

View file

@ -100,7 +100,7 @@ class ResultError : public ResultBase<ResultError<module, description>> {
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);

View file

@ -31,13 +31,13 @@ class IAlarmable : public AlarmableSetBaseHook {
template<typename Clock, typename Duration>
void SetAlarmTime(const std::chrono::time_point<Clock, Duration> &alarmTime)
{
SetAlarmTime(alarmTime);
SetAlarmTimeImpl(alarmTime);
}
template<typename Rep, typename Period>
void SetAlarmIn(const std::chrono::duration<Rep, Period> &alarmTimeOffset)
{
SetAlarmTime(KSystemClock::now() + alarmTimeOffset);
SetAlarmTimeImpl(KSystemClock::now() + alarmTimeOffset);
}
void ClearAlarm();

View file

@ -210,6 +210,12 @@ class KThread final :
/// Takes effect when critical section is left
void HandleSyncObjectSignaled(KSynchronizationObject *syncObj);
template<typename Clock, typename Duration>
Result WaitSynchronization(int &outId, KSynchronizationObject **syncObjs, int numSyncObjs, const std::chrono::time_point<Clock, Duration> &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{};

View file

@ -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<KThread *>::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