From 361764b7dd493c45eea4c7fd18b0184fe72b854a Mon Sep 17 00:00:00 2001 From: babenko Date: Sat, 14 Mar 2026 16:20:52 +0300 Subject: YT-18571: Extract and refactor execution stacks commit_hash:856b6638d9642f4711f5058d77bd58dd78accb8a --- library/cpp/yt/threading/execution_stack.cpp | 146 +++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 library/cpp/yt/threading/execution_stack.cpp (limited to 'library/cpp/yt/threading/execution_stack.cpp') diff --git a/library/cpp/yt/threading/execution_stack.cpp b/library/cpp/yt/threading/execution_stack.cpp new file mode 100644 index 00000000000..35b3281fd4a --- /dev/null +++ b/library/cpp/yt/threading/execution_stack.cpp @@ -0,0 +1,146 @@ +#include "execution_stack.h" + +#if defined(_unix_) +# include +# include +# include +# if !defined(__x86_64__) && !defined(__arm64__) && !defined(__aarch64__) +# error Unsupported platform +# endif +#endif + +#include +#include + +#include + +#include + +#include + +namespace NYT::NThreading { + +//////////////////////////////////////////////////////////////////////////////// + +TExecutionStackBase::TExecutionStackBase(size_t size) + : Size_(RoundUpToPage(size)) +{ + auto cookie = GetRefCountedTypeCookie(); + TRefCountedTrackerFacade::AllocateInstance(cookie); + TRefCountedTrackerFacade::AllocateSpace(cookie, Size_); +} + +TExecutionStackBase::~TExecutionStackBase() +{ + auto cookie = GetRefCountedTypeCookie(); + TRefCountedTrackerFacade::FreeInstance(cookie); + TRefCountedTrackerFacade::FreeSpace(cookie, Size_); +} + +void* TExecutionStackBase::GetStack() const +{ + return Stack_; +} + +size_t TExecutionStackBase::GetSize() const +{ + return Size_; +} + +//////////////////////////////////////////////////////////////////////////////// + +#if defined(_unix_) + +TExecutionStack::TExecutionStack(size_t size) + : TExecutionStackBase(size) +{ + size_t guardSize = GuardPageCount * GetPageSize(); + + int flags = +#if defined(_darwin_) + MAP_ANON | MAP_PRIVATE; +#else + MAP_ANONYMOUS | MAP_PRIVATE; +#endif + + Base_ = reinterpret_cast(::mmap( + 0, + guardSize * 2 + Size_, + PROT_READ | PROT_WRITE, + flags, + -1, + 0)); + + auto handleError = [&] { + AbortProcessDramatically( + EProcessExitCode::OutOfMemory, + Format("Error creating execution stack (Size: %v): %v", + Size_, + TError::FromSystem())); + }; + + if (Base_ == MAP_FAILED) { + handleError(); + } + + if (::mprotect(Base_, guardSize, PROT_NONE) == -1) { + handleError(); + } + + if (::mprotect(Base_ + guardSize + Size_, guardSize, PROT_NONE) == -1) { + handleError(); + } + + Stack_ = Base_ + guardSize; + YT_VERIFY((reinterpret_cast(Stack_) & 15) == 0); +} + +TExecutionStack::~TExecutionStack() +{ + const size_t guardSize = GuardPageCount * GetPageSize(); + ::munmap(Base_, guardSize * 2 + Size_); +} + +#elif defined(_win_) + +TExecutionStack::TExecutionStack(size_t size) + : TExecutionStackBase(size) + , Handle_(::CreateFiber(Size_, &FiberTrampoline, this)) +{ } + +TExecutionStack::~TExecutionStack() +{ + ::DeleteFiber(Handle_); +} + +YT_DEFINE_THREAD_LOCAL(void*, FiberTrampolineOpaque); + +void TExecutionStack::SetOpaque(void* opaque) +{ + FiberTrampolineOpaque() = opaque; +} + +void* TExecutionStack::GetOpaque() +{ + return FiberTrampolineOpaque(); +} + +void TExecutionStack::SetTrampoline(void (*trampoline)(void*)) +{ + YT_ASSERT(!Trampoline_); + Trampoline_ = trampoline; +} + +VOID CALLBACK TExecutionStack::FiberTrampoline(PVOID opaque) +{ + auto* stack = reinterpret_cast(opaque); + stack->Trampoline_(FiberTrampolineOpaque()); +} + +#else +# error Unsupported platform +#endif + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT::NThreading -- cgit v1.3