diff options
author | alexvru <alexvru@ydb.tech> | 2023-02-21 18:21:44 +0300 |
---|---|---|
committer | alexvru <alexvru@ydb.tech> | 2023-02-21 18:21:44 +0300 |
commit | 45c92b417719aba5e3d24726c699b979c6b8ab98 (patch) | |
tree | 28540f116632f91406bc29201e6fe28277131662 /library/cpp | |
parent | 6d27cf6d71a0f582f95db5e9c9940b1a712a631c (diff) | |
download | ydb-45c92b417719aba5e3d24726c699b979c6b8ab98.tar.gz |
Improve TActorCoro
Diffstat (limited to 'library/cpp')
-rw-r--r-- | library/cpp/actors/core/actor_coroutine.cpp | 65 | ||||
-rw-r--r-- | library/cpp/actors/core/actor_coroutine.h | 14 |
2 files changed, 27 insertions, 52 deletions
diff --git a/library/cpp/actors/core/actor_coroutine.cpp b/library/cpp/actors/core/actor_coroutine.cpp index cdd6fdef4c..48c6f4d2d0 100644 --- a/library/cpp/actors/core/actor_coroutine.cpp +++ b/library/cpp/actors/core/actor_coroutine.cpp @@ -3,41 +3,36 @@ #include <util/system/sanitizers.h> #include <util/system/type_name.h> +#include <util/system/info.h> +#include <util/system/protect.h> namespace NActors { - static constexpr size_t StackOverflowGap = 4096; - static char GoodStack[StackOverflowGap]; - - static struct TInitGoodStack { - TInitGoodStack() { - // fill stack with some pseudo-random pattern - for (size_t k = 0; k < StackOverflowGap; ++k) { - GoodStack[k] = k + k * 91; - } - } - } initGoodStack; + static const size_t PageSize = NSystemInfo::GetPageSize(); + + static size_t AlignStackSize(size_t size) { + size += PageSize - (size & PageSize - 1) & PageSize - 1; +#ifndef NDEBUG + size += PageSize; +#endif + return size; + } TActorCoroImpl::TActorCoroImpl(size_t stackSize, bool allowUnhandledPoisonPill, bool allowUnhandledDtor) - : Stack(stackSize) + : Stack(AlignStackSize(stackSize)) , AllowUnhandledPoisonPill(allowUnhandledPoisonPill) , AllowUnhandledDtor(allowUnhandledDtor) , FiberClosure{this, TArrayRef(Stack.Begin(), Stack.End())} , FiberContext(FiberClosure) { #ifndef NDEBUG - char* p; -#if STACK_GROW_DOWN - p = Stack.Begin(); -#else - p = Stack.End() - StackOverflowGap; -#endif - memcpy(p, GoodStack, StackOverflowGap); + ProtectMemory(STACK_GROW_DOWN ? Stack.Begin() : Stack.End() - PageSize, PageSize, EProtectMemoryMode::PM_NONE); #endif } TActorCoroImpl::~TActorCoroImpl() { if (!Finished && !NSan::TSanIsOn()) { // only resume when we have bootstrapped and Run() was entered and not yet finished; in other case simply terminate Y_VERIFY(!PendingEvent); + InvokedFromDtor = true; Resume(); } } @@ -49,8 +44,7 @@ namespace NActors { THolder<IEventHandle> TActorCoroImpl::WaitForEvent(TInstant deadline) { const ui64 cookie = ++WaitCookie; if (deadline != TInstant::Max()) { - ActorContext->ExecutorThread.Schedule(deadline - Now(), new IEventHandle(SelfActorId, {}, new TEvCoroTimeout, - 0, cookie)); + TActivationContext::Schedule(deadline, new IEventHandle(TEvents::TSystem::CoroTimeout, 0, SelfActorId, {}, 0, cookie)); } // ensure we have no unprocessed event and return back to actor system to receive one @@ -76,11 +70,6 @@ namespace NActors { Y_FAIL("no pending event"); } - const TActorContext& TActorCoroImpl::GetActorContext() const { - Y_VERIFY(ActorContext); - return ActorContext.value(); - } - bool TActorCoroImpl::ProcessEvent(THolder<IEventHandle> ev) { Y_VERIFY(!PendingEvent); if (!SelfActorId) { // process bootstrap message, extract actor ids @@ -92,16 +81,14 @@ namespace NActors { } // prepare actor context for in-coroutine use - Y_VERIFY(!ActorContext); TActivationContext *ac = TlsActivationContext; - ActorContext.emplace(ac->Mailbox, ac->ExecutorThread, ac->EventStart, SelfActorId); - TlsActivationContext = &ActorContext.value(); + TActorContext actorContext(ac->Mailbox, ac->ExecutorThread, ac->EventStart, SelfActorId); + TlsActivationContext = &actorContext; Resume(); // drop actor context TlsActivationContext = ac; - ActorContext.reset(); return Finished; } @@ -115,22 +102,11 @@ namespace NActors { // go to actor coroutine BeforeResume(); ActorSystemContext->SwitchTo(&FiberContext); - - // check for stack overflow -#ifndef NDEBUG - const char* p; -#if STACK_GROW_DOWN - p = Stack.Begin(); -#else - p = Stack.End() - StackOverflowGap; -#endif - Y_VERIFY_DEBUG(memcmp(p, GoodStack, StackOverflowGap) == 0); -#endif } void TActorCoroImpl::DoRun() { try { - if (ActorContext) { // ActorContext may be nullptr here if the destructor was invoked before bootstrapping + if (!InvokedFromDtor) { // ActorContext may be nullptr here if the destructor was invoked before bootstrapping Y_VERIFY(!PendingEvent); Run(); } @@ -162,4 +138,9 @@ namespace NActors { } } + STATEFN(TActorCoro::StateFunc) { + if (Impl->ProcessEvent(ev)) { + PassAway(); + } + } } diff --git a/library/cpp/actors/core/actor_coroutine.h b/library/cpp/actors/core/actor_coroutine.h index 16651da81d..fc9ddeef1f 100644 --- a/library/cpp/actors/core/actor_coroutine.h +++ b/library/cpp/actors/core/actor_coroutine.h @@ -15,13 +15,13 @@ namespace NActors { TMappedAllocation Stack; bool AllowUnhandledPoisonPill; bool AllowUnhandledDtor; + bool Finished = false; + bool InvokedFromDtor = false; TContClosure FiberClosure; TExceptionSafeContext FiberContext; TExceptionSafeContext* ActorSystemContext = nullptr; THolder<IEventHandle> PendingEvent; - bool Finished = false; ui64 WaitCookie = 0; - std::optional<TActorContext> ActorContext; protected: TActorIdentity SelfActorId = TActorIdentity(TActorId()); @@ -42,8 +42,6 @@ namespace NActors { } }; - struct TEvCoroTimeout : TEventLocal<TEvCoroTimeout, TEvents::TSystem::CoroTimeout> {}; - protected: struct TPoisonPillException : yexception {}; struct TDtorException : yexception {}; @@ -103,7 +101,7 @@ namespace NActors { } protected: // Actor System compatibility section - const TActorContext& GetActorContext() const; + const TActorContext& GetActorContext() const { return TActivationContext::AsActorContext(); } TActorSystem *GetActorSystem() const { return GetActorContext().ExecutorThread.ActorSystem; } TInstant Now() const { return GetActorContext().Now(); } @@ -163,11 +161,7 @@ namespace NActors { } private: - STATEFN(StateFunc) { - if (Impl->ProcessEvent(ev)) { - PassAway(); - } - } + STATEFN(StateFunc); }; } |