[*] Refactor WorkItemHandler EProcessNext -> ETickType
[*] AuAsync aue 1 regression
This commit is contained in:
parent
24fc2fd90d
commit
286ae14a7b
@ -9,25 +9,24 @@
|
||||
|
||||
namespace Aurora::Async
|
||||
{
|
||||
AUE_DEFINE(ETickType,
|
||||
(
|
||||
eFinished,
|
||||
eRerun,
|
||||
eSchedule,
|
||||
eFailed
|
||||
));
|
||||
|
||||
struct IWorkItemHandler
|
||||
{
|
||||
enum class EProcessNext
|
||||
{
|
||||
eInvalid = -1,
|
||||
eFinished = 0,
|
||||
eRerun,
|
||||
eSchedule,
|
||||
eFailed
|
||||
};
|
||||
|
||||
struct ProcessInfo
|
||||
{
|
||||
ProcessInfo(bool finished) : type(finished ? EProcessNext::eFinished : EProcessNext::eFailed) {}
|
||||
ProcessInfo(EProcessNext type) : type(type) {}
|
||||
ProcessInfo(const AuList<AuSPtr<IWorkItem>> &blockedBy) : type(EProcessNext::eSchedule), waitFor(blockedBy) {}
|
||||
ProcessInfo(bool finished) : type(finished ? ETickType::eFinished : ETickType::eFailed) {}
|
||||
ProcessInfo(ETickType type) : type(type) {}
|
||||
ProcessInfo(const AuList<AuSPtr<IWorkItem>> &blockedBy) : type(ETickType::eSchedule), waitFor(blockedBy) {}
|
||||
// ...
|
||||
|
||||
EProcessNext type;
|
||||
ETickType type;
|
||||
AuList<AuSPtr<IWorkItem>> waitFor;
|
||||
AuUInt32 reschedMs {};
|
||||
AuUInt64 reschedNs {};
|
||||
@ -40,9 +39,8 @@ namespace Aurora::Async
|
||||
virtual void DispatchFrame(ProcessInfo &info) = 0;
|
||||
|
||||
/// A really terrible name for the overloadable method that serves as the critical failure callback
|
||||
/// You have a 'shutdown'/free function you can overload, it's called the dtor
|
||||
/// Don't moan about the shitty naming of this, im not refactoring it
|
||||
virtual void Shutdown() = 0;
|
||||
/// This may run from any thread
|
||||
virtual void OnFailure() {};
|
||||
|
||||
virtual void *GetPrivateData() { return nullptr; }
|
||||
};
|
||||
|
@ -22,7 +22,7 @@ namespace Aurora::Async
|
||||
|
||||
private:
|
||||
#if !defined(_CPPSHARP)
|
||||
void DispatchFrame(ProcessInfo &info) override
|
||||
inline void DispatchFrame(ProcessInfo &info) override
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -34,7 +34,7 @@ namespace Aurora::Async
|
||||
}
|
||||
}
|
||||
|
||||
void Shutdown() override
|
||||
inline void OnFailure() override
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -66,12 +66,12 @@ namespace Aurora::Async
|
||||
{
|
||||
if (!frame)
|
||||
{
|
||||
info.type = IWorkItemHandler::EProcessNext::eFinished;
|
||||
info.type = IWorkItemHandler::ETickType::eFinished;
|
||||
return;
|
||||
}
|
||||
}
|
||||
frame();
|
||||
info.type = IWorkItemHandler::EProcessNext::eFinished;
|
||||
info.type = IWorkItemHandler::ETickType::eFinished;
|
||||
}
|
||||
|
||||
void Shutdown() override
|
||||
|
@ -175,7 +175,7 @@ namespace Aurora::Async
|
||||
}
|
||||
}
|
||||
|
||||
void Shutdown() override
|
||||
void OnFailure() override
|
||||
{
|
||||
AU_LOCK_GUARD(this->lock_);
|
||||
ShutdownNoLock();
|
||||
|
@ -54,29 +54,43 @@ namespace Aurora::Async
|
||||
return AU_SHARED_FROM_THIS;
|
||||
}
|
||||
|
||||
bool WorkItem::WaitForLocked(const AuList<AuSPtr<IWorkItem>> &workItems)
|
||||
{
|
||||
for (auto &workItem : workItems)
|
||||
{
|
||||
auto dependency = AuReinterpretCast<WorkItem>(workItem);
|
||||
AU_LOCK_GUARD(dependency->lock);
|
||||
|
||||
if (dependency->HasFailed())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!AuTryInsert(dependency->waiters_, AuSharedFromThis()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!AuTryInsert(this->waitOn_, workItem))
|
||||
{
|
||||
AuTryRemove(dependency->waiters_, AuSharedFromThis());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
AuSPtr<IWorkItem> WorkItem::WaitFor(const AuList<AuSPtr<IWorkItem>> &workItems)
|
||||
{
|
||||
bool status {};
|
||||
|
||||
{
|
||||
AU_LOCK_GUARD(this->lock);
|
||||
|
||||
for (auto &workItem : workItems)
|
||||
{
|
||||
auto dependency = AuReinterpretCast<WorkItem>(workItem);
|
||||
AU_LOCK_GUARD(dependency->lock);
|
||||
|
||||
if (dependency->HasFailed())
|
||||
{
|
||||
status = true;
|
||||
}
|
||||
|
||||
dependency->waiters_.push_back(shared_from_this());
|
||||
this->waitOn_.push_back(workItem);
|
||||
}
|
||||
status = WaitForLocked(workItems);
|
||||
}
|
||||
|
||||
if (status)
|
||||
if (!status)
|
||||
{
|
||||
Fail();
|
||||
}
|
||||
@ -100,7 +114,7 @@ namespace Aurora::Async
|
||||
|
||||
AuSPtr<IWorkItem> WorkItem::SetSchedTimeAbs(AuUInt32 ms)
|
||||
{
|
||||
this->dispatchTimeNs_ = AuUInt64(ms) * AuUInt64(1000000);
|
||||
this->dispatchTimeNs_ = AuUInt64(ms) * AuMSToNS<AuUInt64>(ms);
|
||||
return AU_SHARED_FROM_THIS;
|
||||
}
|
||||
|
||||
@ -112,13 +126,13 @@ namespace Aurora::Async
|
||||
|
||||
AuSPtr<IWorkItem> WorkItem::SetSchedTime(AuUInt32 ms)
|
||||
{
|
||||
this->dispatchTimeNs_ = Time::CurrentClockNS() + (AuUInt64(ms) * AuUInt64(1000000));
|
||||
this->dispatchTimeNs_ = Time::CurrentClockNS() + AuMSToNS<AuUInt64>(ms);
|
||||
return AU_SHARED_FROM_THIS;
|
||||
}
|
||||
|
||||
AuSPtr<IWorkItem> WorkItem::AddDelayTime(AuUInt32 ms)
|
||||
{
|
||||
this->delayTimeNs_ += AuUInt64(ms) * AuUInt64(1000000);
|
||||
this->delayTimeNs_ += AuUInt64(ms) * AuMSToNS<AuUInt64>(ms);
|
||||
return AU_SHARED_FROM_THIS;
|
||||
}
|
||||
|
||||
@ -138,6 +152,11 @@ namespace Aurora::Async
|
||||
{
|
||||
AU_LOCK_GUARD(lock);
|
||||
|
||||
DispatchExLocked(check);
|
||||
}
|
||||
|
||||
void WorkItem::DispatchExLocked(bool check)
|
||||
{
|
||||
if (check)
|
||||
{
|
||||
if (this->dispatchPending_)
|
||||
@ -211,17 +230,17 @@ namespace Aurora::Async
|
||||
|
||||
switch (info.type)
|
||||
{
|
||||
case IWorkItemHandler::EProcessNext::eFinished:
|
||||
case ETickType::eFinished:
|
||||
{
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
case IWorkItemHandler::EProcessNext::eInvalid:
|
||||
case ETickType::eEnumInvalid:
|
||||
{
|
||||
SysPanic("Handle Invalid");
|
||||
break;
|
||||
}
|
||||
case IWorkItemHandler::EProcessNext::eSchedule:
|
||||
case ETickType::eSchedule:
|
||||
{
|
||||
if (info.reschedMs)
|
||||
{
|
||||
@ -239,16 +258,20 @@ namespace Aurora::Async
|
||||
{
|
||||
SetSchedTimeNsAbs(info.reschedNs);
|
||||
}
|
||||
WaitFor(info.waitFor);
|
||||
|
||||
if (!WaitForLocked(info.waitFor))
|
||||
{
|
||||
Fail();
|
||||
}
|
||||
|
||||
}
|
||||
[[fallthrough]];
|
||||
case IWorkItemHandler::EProcessNext::eRerun:
|
||||
case ETickType::eRerun:
|
||||
{
|
||||
DispatchEx(false);
|
||||
DispatchExLocked(false);
|
||||
return;
|
||||
}
|
||||
case IWorkItemHandler::EProcessNext::eFailed:
|
||||
case ETickType::eFailed:
|
||||
{
|
||||
Fail();
|
||||
return;
|
||||
@ -273,7 +296,7 @@ namespace Aurora::Async
|
||||
|
||||
if (auto task_ = AuExchange(this->task_, {}))
|
||||
{
|
||||
task_->Shutdown();
|
||||
task_->OnFailure();
|
||||
}
|
||||
|
||||
for (auto &waiter : this->waiters_)
|
||||
|
@ -46,7 +46,12 @@ namespace Aurora::Async
|
||||
void SetPrio(float val) override;
|
||||
|
||||
private:
|
||||
|
||||
bool WaitForLocked(const AuList<AuSPtr<IWorkItem>> &workItem);
|
||||
|
||||
void DispatchEx(bool check);
|
||||
void DispatchExLocked(bool check);
|
||||
|
||||
AuSPtr<IWorkItemHandler> task_;
|
||||
WorkerId_t worker_;
|
||||
float prio_ = 0.5f;
|
||||
|
Loading…
Reference in New Issue
Block a user