[+] Added end of loop queue poll hook for IO Processor frame tick batching

This commit is contained in:
Reece Wilson 2022-07-06 03:40:09 +01:00
parent 7fb73ccdb4
commit f2791e360b
7 changed files with 74 additions and 5 deletions

View File

@ -11,6 +11,8 @@
#include "IOProcessorItems.hpp"
#include "IOProcessor.hpp"
#include "IOPipeProcessor.hpp"
#include "Loop/Loop.hpp"
#include "Loop/LoopQueue.hpp"
namespace Aurora::IO
{
@ -90,6 +92,21 @@ namespace Aurora::IO
return this->items.AddFrameOrFallback(AuStaticCast<IOProcessorItem>(ioEvent));
}
void IOProcessor::TickForHack(const AuSPtr<IIOProcessorItem> &ioEvent)
{
SysAssert(this->TickForRegister(ioEvent));
if (AuExchange(this->bScheduled_, true))
{
return;
}
AuStaticCast<Loop::LoopQueue>(this->loopQueue)->AddHook([that = AuSharedFromThis()]()
{
that->RunTick();
});
}
AuUInt32 IOProcessor::TickFor(const AuSPtr<IIOProcessorItem> &ioEvent)
{
SysAssert(TickForRegister(ioEvent));
@ -127,6 +144,7 @@ namespace Aurora::IO
return 0;
}
this->bScheduled_ = false;
this->bFrameStart = false;
AU_LOCK_GUARD(this->items.mutex);

View File

@ -29,6 +29,8 @@ namespace Aurora::IO
AuUInt32 TickFor(const AuSPtr<IIOProcessorItem> &ioEvent);
bool TickForRegister(const AuSPtr<IIOProcessorItem> &ioEvent);
void TickForHack(const AuSPtr<IIOProcessorItem> &ioEvent);
bool bScheduled_ {};
AuUInt32 ManualTick() override;
void DispatchFrame(ProcessInfo &info) override;

View File

@ -68,10 +68,17 @@ namespace Aurora::IO
if (!this->parent->IsTickOnly())
{
if (!this->parent->bFrameStart)
{
if (force)
{
this->parent->TickFor(AuSharedFromThis());
}
else
{
this->parent->TickForHack(AuSharedFromThis());
}
}
else
{
this->parent->TickForRegister(AuSharedFromThis());
}

View File

@ -954,6 +954,11 @@ namespace Aurora::IO::Loop
return AuMakeTuple(true, bShouldRemove, bOverload);
}
bool LoopQueue::AddHook(const AuFunction<void> &func)
{
return AuTryInsert(this->epilogueHooks_, func);
}
AUKN_SYM AuSPtr<ILoopQueue> NewLoopQueue()
{
auto queue = AuMakeShared<LoopQueue>();

View File

@ -731,6 +731,8 @@ namespace Aurora::IO::Loop
{
ret++;
}
PumpHooks();
}
while (WaitForSingleObject(this->hEvent_, 0) == WAIT_OBJECT_0);
@ -751,6 +753,8 @@ namespace Aurora::IO::Loop
{
return trigger;
}
PumpHooks();
}
while (WaitForSingleObject(this->hEvent_, 0) == WAIT_OBJECT_0);
@ -770,6 +774,8 @@ namespace Aurora::IO::Loop
{
ret++;
}
PumpHooks();
}
while (WaitForSingleObject(this->hEvent_, 0) == WAIT_OBJECT_0);
@ -788,6 +794,7 @@ namespace Aurora::IO::Loop
{
return trigger;
}
PumpHooks();
}
while (WaitForSingleObject(this->hEvent_, 0) == WAIT_OBJECT_0);
@ -1267,6 +1274,20 @@ namespace Aurora::IO::Loop
}
}
bool LoopQueue::AddHook(const AuFunction<void()> &func)
{
return AuTryInsert(this->epilogueHooks_, func);
}
void LoopQueue::PumpHooks()
{
auto c = AuExchange(this->epilogueHooks_, {});
for (auto &a : c)
{
a();
}
}
AUKN_SYM AuSPtr<ILoopQueue> NewLoopQueue()
{
return AuMakeShared<LoopQueue>();

View File

@ -8,14 +8,18 @@
#pragma once
#include "ILoopSourceEx.hpp"
#include "LoopQueue.hpp"
namespace Aurora::IO::Loop
{
struct LoopQueue : ILoopQueue
struct LoopQueue : ILoopQueue//, ILoopEpilogueHook
{
LoopQueue();
~LoopQueue();
bool AddHook(const AuFunction<void()> &func);// override;
void PumpHooks();
bool SourceAdd(const AuSPtr<ILoopSource> &source) override;
bool SourceAddWithTimeout(const AuSPtr<ILoopSource> &source, AuUInt32 ms) override;
bool SourceRemove(const AuSPtr<ILoopSource> &source) override;
@ -41,6 +45,8 @@ namespace Aurora::IO::Loop
void Sync();
void Unlock();
bool bCheckForDups {};
bool bCheckForForce {};
private:
@ -62,9 +68,10 @@ namespace Aurora::IO::Loop
AuSPtr<ILoopSourceEx> source;
AuSPtr<ILoopSource> sourceBase;
AuThreadPrimitives::SpinLock lock; // im too brain dead to think of a solution to the AddCallback thread safety issue, so i'm going to optimize Wait[...]s subscriber lookup with filtered ccaches in here, protected by this spinlock
AuUInt64 timeoutAbs;
AuUInt64 timeoutAbs {};
LoopQueue *parent {};
SourceCallbacks callbacks;
bool invalidateItr {};
bool ConsiderTimeout(AuUInt64 time) const;
AuPair<bool, bool> DoWork(LoopQueue* queue, AuUInt handle);
};
@ -85,7 +92,6 @@ namespace Aurora::IO::Loop
AuThreadPrimitives::SpinLock sourceMutex_;
AuList<AuTuple<AuSPtr<ILoopSource>, AuUInt32, SourceCallbacks>> addedSources_;
//
AuList<AuSPtr<ILoopSourceSubscriber>> globalSubcribers_;
// OS Cache
@ -179,6 +185,8 @@ namespace Aurora::IO::Loop
};
AuList<AuFunction<void()>> epilogueHooks_;
friend struct Iteartor;
};
}

View File

@ -7,6 +7,14 @@
***/
#pragma once
namespace Aurora::IO::Loop
{
struct ILoopEpilogueHook
{
virtual bool AddHook(const AuFunction<void()> &func) = 0;
};
}
#if defined(AURORA_IS_MODERNNT_DERIVED)
#include "LoopQueue.NT.hpp"
#elif defined(AURORA_PLATFORM_LINUX)