diff options
author | Anton Samokhvalov <[email protected]> | 2022-02-10 16:45:15 +0300 |
---|---|---|
committer | Daniil Cherednik <[email protected]> | 2022-02-10 16:45:15 +0300 |
commit | 72cb13b4aff9bc9cf22e49251bc8fd143f82538f (patch) | |
tree | da2c34829458c7d4e74bdfbdf85dff449e9e7fb8 /util/system/context.cpp | |
parent | 778e51ba091dc39e7b7fcab2b9cf4dbedfb6f2b5 (diff) |
Restoring authorship annotation for Anton Samokhvalov <[email protected]>. Commit 1 of 2.
Diffstat (limited to 'util/system/context.cpp')
-rw-r--r-- | util/system/context.cpp | 544 |
1 files changed, 272 insertions, 272 deletions
diff --git a/util/system/context.cpp b/util/system/context.cpp index ad993090884..5b095be8a0d 100644 --- a/util/system/context.cpp +++ b/util/system/context.cpp @@ -1,336 +1,336 @@ #include "compiler.h" -#include "defaults.h" -#include "event.h" -#include "thread.h" - -#include <cstdlib> //for abort() - -#if defined(_win_) - #include "winint.h" -#endif - -#if defined(_unix_) - #include <cxxabi.h> - - #if !defined(Y_CXA_EH_GLOBALS_COMPLETE) -namespace __cxxabiv1 { - struct __cxa_eh_globals { - void* caughtExceptions; - unsigned int uncaughtExceptions; - }; - - extern "C" __cxa_eh_globals* __cxa_get_globals(); -} - #endif -#endif - +#include "defaults.h" +#include "event.h" +#include "thread.h" + +#include <cstdlib> //for abort() + +#if defined(_win_) + #include "winint.h" +#endif + +#if defined(_unix_) + #include <cxxabi.h> + + #if !defined(Y_CXA_EH_GLOBALS_COMPLETE) +namespace __cxxabiv1 { + struct __cxa_eh_globals { + void* caughtExceptions; + unsigned int uncaughtExceptions; + }; + + extern "C" __cxa_eh_globals* __cxa_get_globals(); +} + #endif +#endif + #include <util/stream/output.h> #include <util/generic/yexception.h> - -#define FROM_CONTEXT_IMPL -#include "context.h" - -void ITrampoLine::DoRun() { -} - -void ITrampoLine::DoRunNaked() { - try { - DoRun(); - } catch (...) { + +#define FROM_CONTEXT_IMPL +#include "context.h" + +void ITrampoLine::DoRun() { +} + +void ITrampoLine::DoRunNaked() { + try { + DoRun(); + } catch (...) { Cerr << "Uncaught exception in coroutine: " << CurrentExceptionMessage() << "\n"; - } - - abort(); -} - -static inline void Run(void* arg) { - ((ITrampoLine*)arg)->DoRunNaked(); -} - -#if defined(USE_JUMP_CONT) -extern "C" void __mylongjmp(__myjmp_buf env, int val) __attribute__((__noreturn__)); -extern "C" int __mysetjmp(__myjmp_buf env) __attribute__((__returns_twice__)); - -namespace { + } + + abort(); +} + +static inline void Run(void* arg) { + ((ITrampoLine*)arg)->DoRunNaked(); +} + +#if defined(USE_JUMP_CONT) +extern "C" void __mylongjmp(__myjmp_buf env, int val) __attribute__((__noreturn__)); +extern "C" int __mysetjmp(__myjmp_buf env) __attribute__((__returns_twice__)); + +namespace { class TStackType { - public: + public: inline TStackType(TArrayRef<char> range) noexcept - #if defined(STACK_GROW_DOWN) + #if defined(STACK_GROW_DOWN) : Data_(range.data() + range.size()) - #else + #else : Data_(range.data() + STACK_ALIGN) - #endif - { - ReAlign(); - } - + #endif + { + ReAlign(); + } + inline ~TStackType() = default; - + inline void ReAlign() noexcept { - Data_ = AlignStackPtr(Data_); - } - - template <class T> + Data_ = AlignStackPtr(Data_); + } + + template <class T> inline void Push(T t) noexcept { - #if defined(STACK_GROW_DOWN) - Data_ -= sizeof(T); - *((T*)Data_) = t; - #else - *((T*)Data_) = t; - Data_ += sizeof(T); - #endif - } - + #if defined(STACK_GROW_DOWN) + Data_ -= sizeof(T); + *((T*)Data_) = t; + #else + *((T*)Data_) = t; + Data_ += sizeof(T); + #endif + } + inline char* StackPtr() noexcept { - return Data_; - } - - private: + return Data_; + } + + private: static inline char* AlignStackPtr(char* ptr) noexcept { - #if defined(STACK_GROW_DOWN) - return AlignDown(ptr, STACK_ALIGN); - #else - return AlignUp(ptr, STACK_ALIGN); - #endif - } - - private: - char* Data_; - }; - + #if defined(STACK_GROW_DOWN) + return AlignDown(ptr, STACK_ALIGN); + #else + return AlignUp(ptr, STACK_ALIGN); + #endif + } + + private: + char* Data_; + }; + static inline void*& JmpBufReg(__myjmp_buf& buf, size_t n) noexcept { - return (((void**)(void*)(buf))[n]); - } - + return (((void**)(void*)(buf))[n]); + } + static inline void*& JmpBufStackReg(__myjmp_buf& buf) noexcept { - return JmpBufReg(buf, STACK_CNT); - } - + return JmpBufReg(buf, STACK_CNT); + } + static inline void*& JmpBufProgrReg(__myjmp_buf& buf) noexcept { - return JmpBufReg(buf, PROGR_CNT); - } - + return JmpBufReg(buf, PROGR_CNT); + } + static inline void*& JmpBufFrameReg(__myjmp_buf& buf) noexcept { return JmpBufReg(buf, FRAME_CNT); } - #if defined(_x86_64_) + #if defined(_x86_64_) // not sure if Y_NO_SANITIZE is needed - Y_NO_SANITIZE("address") - Y_NO_SANITIZE("memory") extern "C" void ContextTrampoLine(void*, void*, void*, void*, void*, void*, // register arguments, no defined value - /* first argument passed through the stack */ void* t1, - /* second argument passed through the stack */ void* t2) { + Y_NO_SANITIZE("address") + Y_NO_SANITIZE("memory") extern "C" void ContextTrampoLine(void*, void*, void*, void*, void*, void*, // register arguments, no defined value + /* first argument passed through the stack */ void* t1, + /* second argument passed through the stack */ void* t2) { Y_ASSERT(t1 == t2); Run(t1); } - #else + #else Y_NO_SANITIZE("address") - Y_NO_SANITIZE("memory") static void ContextTrampoLine() { - void** argPtr = (void**)((char*)AlignUp(&argPtr + EXTRA_PUSH_ARGS, STACK_ALIGN) + STACK_ALIGN); + Y_NO_SANITIZE("memory") static void ContextTrampoLine() { + void** argPtr = (void**)((char*)AlignUp(&argPtr + EXTRA_PUSH_ARGS, STACK_ALIGN) + STACK_ALIGN); Y_ASSERT(*(argPtr - 1) == *(argPtr - 2)); - - Run(*(argPtr - 1)); - } - #endif -} - -TContMachineContext::TSan::TSan() noexcept - : TL(nullptr) -{ -} - -TContMachineContext::TSan::TSan(const TContClosure& c) noexcept + + Run(*(argPtr - 1)); + } + #endif +} + +TContMachineContext::TSan::TSan() noexcept + : TL(nullptr) +{ +} + +TContMachineContext::TSan::TSan(const TContClosure& c) noexcept : NSan::TFiberContext(c.Stack.data(), c.Stack.size(), c.ContName) - , TL(c.TrampoLine) -{ -} - + , TL(c.TrampoLine) +{ +} + void TContMachineContext::TSan::DoRunNaked() { - AfterSwitch(); + AfterSwitch(); TL->DoRunNaked(); - BeforeFinish(); -} - -TContMachineContext::TContMachineContext(const TContClosure& c) - #if defined(_asan_enabled_) || defined(_tsan_enabled_) - : San_(c) - #endif -{ + BeforeFinish(); +} + +TContMachineContext::TContMachineContext(const TContClosure& c) + #if defined(_asan_enabled_) || defined(_tsan_enabled_) + : San_(c) + #endif +{ TStackType stack(c.Stack); - - /* - * arg, and align data - */ - - #if defined(_asan_enabled_) - auto trampoline = &San_; - #else - auto trampoline = c.TrampoLine; - #endif - - #if defined(_x86_64_) + + /* + * arg, and align data + */ + + #if defined(_asan_enabled_) + auto trampoline = &San_; + #else + auto trampoline = c.TrampoLine; + #endif + + #if defined(_x86_64_) stack.ReAlign(); // push twice to preserve alignment by 16 stack.Push(trampoline); // second stack argument stack.Push(trampoline); // first stack argument stack.Push(nullptr); // fake return address - #else - stack.Push(trampoline); - stack.Push(trampoline); - stack.ReAlign(); - /* - * fake return address - */ - for (size_t i = 0; i < EXTRA_PUSH_ARGS; ++i) { + #else + stack.Push(trampoline); + stack.Push(trampoline); + stack.ReAlign(); + /* + * fake return address + */ + for (size_t i = 0; i < EXTRA_PUSH_ARGS; ++i) { stack.Push(nullptr); - } - #endif - - __mysetjmp(Buf_); - + } + #endif + + __mysetjmp(Buf_); + JmpBufProgrReg(Buf_) = reinterpret_cast<void*>(ContextTrampoLine); - JmpBufStackReg(Buf_) = stack.StackPtr(); + JmpBufStackReg(Buf_) = stack.StackPtr(); JmpBufFrameReg(Buf_) = nullptr; -} - +} + void TContMachineContext::SwitchTo(TContMachineContext* next) noexcept { if (Y_LIKELY(__mysetjmp(Buf_) == 0)) { - #if defined(_asan_enabled_) || defined(_tsan_enabled_) + #if defined(_asan_enabled_) || defined(_tsan_enabled_) next->San_.BeforeSwitch(&San_); - #endif - __mylongjmp(next->Buf_, 1); - } else { - #if defined(_asan_enabled_) - San_.AfterSwitch(); - #endif - } -} + #endif + __mylongjmp(next->Buf_, 1); + } else { + #if defined(_asan_enabled_) + San_.AfterSwitch(); + #endif + } +} #elif defined(_win_) && defined(_32_) void __stdcall ContextTrampoLine(void* arg) { Run(arg); } -#else -void ContextTrampoLine(void* arg) { - Run(arg); -} -#endif - -#if defined(USE_FIBER_CONT) +#else +void ContextTrampoLine(void* arg) { + Run(arg); +} +#endif + +#if defined(USE_FIBER_CONT) TContMachineContext::TContMachineContext() - : Fiber_(ConvertThreadToFiber(this)) - , MainFiber_(true) + : Fiber_(ConvertThreadToFiber(this)) + , MainFiber_(true) { Y_ENSURE(Fiber_, TStringBuf("fiber error")); } -TContMachineContext::TContMachineContext(const TContClosure& c) +TContMachineContext::TContMachineContext(const TContClosure& c) : Fiber_(CreateFiber(c.Stack.size(), (LPFIBER_START_ROUTINE)ContextTrampoLine, (LPVOID)c.TrampoLine)) - , MainFiber_(false) + , MainFiber_(false) { Y_ENSURE(Fiber_, TStringBuf("fiber error")); -} - +} + TContMachineContext::~TContMachineContext() { - if (MainFiber_) { - ConvertFiberToThread(); - } else { - DeleteFiber(Fiber_); - } -} - + if (MainFiber_) { + ConvertFiberToThread(); + } else { + DeleteFiber(Fiber_); + } +} + void TContMachineContext::SwitchTo(TContMachineContext* next) noexcept { - SwitchToFiber(next->Fiber_); -} -#endif - -#if defined(USE_GENERIC_CONT) - #include <pthread.h> - -struct TContMachineContext::TImpl { - inline TImpl() + SwitchToFiber(next->Fiber_); +} +#endif + +#if defined(USE_GENERIC_CONT) + #include <pthread.h> + +struct TContMachineContext::TImpl { + inline TImpl() : TL(nullptr) - , Finish(false) - { - } - - inline TImpl(const TContClosure& c) - : TL(c.TrampoLine) - , Finish(false) - { + , Finish(false) + { + } + + inline TImpl(const TContClosure& c) + : TL(c.TrampoLine) + , Finish(false) + { Thread.Reset(new TThread(TThread::TParams(Run, this).SetStackSize(c.Stack.size()).SetStackPointer((void*)c.Stack.data()))); - Thread->Start(); - } - + Thread->Start(); + } + inline ~TImpl() { - if (Thread) { - Finish = true; - Signal(); - Thread->Join(); - } - } - + if (Thread) { + Finish = true; + Signal(); + Thread->Join(); + } + } + inline void SwitchTo(TImpl* next) noexcept { - next->Signal(); - Wait(); - } - - static void* Run(void* self) { - ((TImpl*)self)->DoRun(); - - return nullptr; - } - - inline void DoRun() { - Wait(); - TL->DoRun(); - } - + next->Signal(); + Wait(); + } + + static void* Run(void* self) { + ((TImpl*)self)->DoRun(); + + return nullptr; + } + + inline void DoRun() { + Wait(); + TL->DoRun(); + } + inline void Signal() noexcept { - Event.Signal(); - } - + Event.Signal(); + } + inline void Wait() noexcept { - Event.Wait(); - - if (Finish) { - // TODO - need proper TThread::Exit(), have some troubles in win32 now - pthread_exit(0); - } - } - - TAutoEvent Event; - THolder<TThread> Thread; - ITrampoLine* TL; - bool Finish; -}; - -TContMachineContext::TContMachineContext() - : Impl_(new TImpl()) -{ -} - -TContMachineContext::TContMachineContext(const TContClosure& c) - : Impl_(new TImpl(c)) -{ -} - + Event.Wait(); + + if (Finish) { + // TODO - need proper TThread::Exit(), have some troubles in win32 now + pthread_exit(0); + } + } + + TAutoEvent Event; + THolder<TThread> Thread; + ITrampoLine* TL; + bool Finish; +}; + +TContMachineContext::TContMachineContext() + : Impl_(new TImpl()) +{ +} + +TContMachineContext::TContMachineContext(const TContClosure& c) + : Impl_(new TImpl(c)) +{ +} + TContMachineContext::~TContMachineContext() { -} - +} + void TContMachineContext::SwitchTo(TContMachineContext* next) noexcept { - Impl_->SwitchTo(next->Impl_.Get()); -} -#endif - -void TExceptionSafeContext::SwitchTo(TExceptionSafeContext* to) noexcept { -#if defined(_unix_) - static_assert(sizeof(__cxxabiv1::__cxa_eh_globals) == sizeof(Buf_), "size mismatch of __cxa_eh_globals structure"); - - auto* eh = __cxxabiv1::__cxa_get_globals(); - ::memcpy(Buf_, eh, sizeof(Buf_)); - ::memcpy(eh, to->Buf_, sizeof(Buf_)); -#endif - - TContMachineContext::SwitchTo(to); -} + Impl_->SwitchTo(next->Impl_.Get()); +} +#endif + +void TExceptionSafeContext::SwitchTo(TExceptionSafeContext* to) noexcept { +#if defined(_unix_) + static_assert(sizeof(__cxxabiv1::__cxa_eh_globals) == sizeof(Buf_), "size mismatch of __cxa_eh_globals structure"); + + auto* eh = __cxxabiv1::__cxa_get_globals(); + ::memcpy(Buf_, eh, sizeof(Buf_)); + ::memcpy(eh, to->Buf_, sizeof(Buf_)); +#endif + + TContMachineContext::SwitchTo(to); +} |