summaryrefslogtreecommitdiffstats
path: root/util/system/thread.cpp
diff options
context:
space:
mode:
authorAnton Samokhvalov <[email protected]>2022-02-10 16:45:17 +0300
committerDaniil Cherednik <[email protected]>2022-02-10 16:45:17 +0300
commitd3a398281c6fd1d3672036cb2d63f842d2cb28c5 (patch)
treedd4bd3ca0f36b817e96812825ffaf10d645803f2 /util/system/thread.cpp
parent72cb13b4aff9bc9cf22e49251bc8fd143f82538f (diff)
Restoring authorship annotation for Anton Samokhvalov <[email protected]>. Commit 2 of 2.
Diffstat (limited to 'util/system/thread.cpp')
-rw-r--r--util/system/thread.cpp634
1 files changed, 317 insertions, 317 deletions
diff --git a/util/system/thread.cpp b/util/system/thread.cpp
index 7d918f8686f..6236746c2d9 100644
--- a/util/system/thread.cpp
+++ b/util/system/thread.cpp
@@ -1,12 +1,12 @@
-#include "tls.h"
-#include "thread.h"
-#include "thread.i"
-
+#include "tls.h"
+#include "thread.h"
+#include "thread.i"
+
#include <util/generic/ptr.h>
#include <util/generic/ymath.h>
-#include <util/generic/ylimits.h>
+#include <util/generic/ylimits.h>
#include <util/generic/yexception.h>
-#include "yassert.h"
+#include "yassert.h"
#include <utility>
#if defined(_glibc_)
@@ -16,12 +16,12 @@
#endif
#if defined(_unix_)
- #include <pthread.h>
+ #include <pthread.h>
#include <sys/types.h>
#elif defined(_win_)
- #include "dynlib.h"
- #include <util/charset/wide.h>
- #include <util/generic/scope.h>
+ #include "dynlib.h"
+ #include <util/charset/wide.h>
+ #include <util/generic/scope.h>
#else
#error "FIXME"
#endif
@@ -37,174 +37,174 @@ bool SetHighestThreadPriority() {
#endif
}
-namespace {
+namespace {
using TParams = TThread::TParams;
using TId = TThread::TId;
-
- inline void SetThrName(const TParams& p) {
- try {
+
+ inline void SetThrName(const TParams& p) {
+ try {
if (p.Name) {
TThread::SetCurrentThreadName(p.Name.data());
- }
- } catch (...) {
- // ¯\_(ツ)_/¯
- }
- }
-
+ }
+ } catch (...) {
+ // ¯\_(ツ)_/¯
+ }
+ }
+
inline size_t StackSize(const TParams& p) noexcept {
- if (p.StackSize) {
- return FastClp2(p.StackSize);
- }
-
- return 0;
- }
-
-#if defined(_win_)
- class TWinThread {
- struct TMyParams: public TParams, public TThrRefBase {
- inline TMyParams(const TParams& p)
- : TParams(p)
- , Result(0)
- {
- }
-
- void* Result;
- };
-
+ if (p.StackSize) {
+ return FastClp2(p.StackSize);
+ }
+
+ return 0;
+ }
+
+#if defined(_win_)
+ class TWinThread {
+ struct TMyParams: public TParams, public TThrRefBase {
+ inline TMyParams(const TParams& p)
+ : TParams(p)
+ , Result(0)
+ {
+ }
+
+ void* Result;
+ };
+
using TParamsRef = TIntrusivePtr<TMyParams>;
-
- public:
- inline TWinThread(const TParams& params)
- : P_(new TMyParams(params))
- , Handle(0)
- #if _WIN32_WINNT < 0x0502
- , ThreadId(0)
- #endif
- {
- }
+
+ public:
+ inline TWinThread(const TParams& params)
+ : P_(new TMyParams(params))
+ , Handle(0)
+ #if _WIN32_WINNT < 0x0502
+ , ThreadId(0)
+ #endif
+ {
+ }
inline bool Running() const noexcept {
- return Handle != 0;
- }
-
+ return Handle != 0;
+ }
+
inline TId SystemThreadId() const noexcept {
- #if _WIN32_WINNT < 0x0502
+ #if _WIN32_WINNT < 0x0502
return (TId)ThreadId;
- #else
- return (TId)GetThreadId(Handle);
- #endif
- }
-
- inline void* Join() {
- ::WaitForSingleObject(Handle, INFINITE);
- ::CloseHandle(Handle);
-
- return P_->Result;
- }
-
- inline void Detach() {
- ::CloseHandle(Handle);
- }
+ #else
+ return (TId)GetThreadId(Handle);
+ #endif
+ }
+
+ inline void* Join() {
+ ::WaitForSingleObject(Handle, INFINITE);
+ ::CloseHandle(Handle);
+
+ return P_->Result;
+ }
+
+ inline void Detach() {
+ ::CloseHandle(Handle);
+ }
static ui32 __stdcall Proxy(void* ptr) {
NTls::TCleaner cleaner;
-
- (void)cleaner;
-
- {
- TParamsRef p((TMyParams*)(ptr));
-
- //drop counter, gotten in Start()
- p->UnRef();
-
- SetThrName(*p);
- p->Result = p->Proc(p->Data);
- }
-
+
+ (void)cleaner;
+
+ {
+ TParamsRef p((TMyParams*)(ptr));
+
+ //drop counter, gotten in Start()
+ p->UnRef();
+
+ SetThrName(*p);
+ p->Result = p->Proc(p->Data);
+ }
+
return 0;
- }
-
- inline void Start() {
+ }
+
+ inline void Start() {
//do not do this, kids, at home
P_->Ref();
- #if _WIN32_WINNT < 0x0502
+ #if _WIN32_WINNT < 0x0502
Handle = reinterpret_cast<HANDLE>(::_beginthreadex(nullptr, (unsigned)StackSize(*P_), Proxy, (void*)P_.Get(), 0, &ThreadId));
- #else
+ #else
Handle = reinterpret_cast<HANDLE>(::_beginthreadex(nullptr, (unsigned)StackSize(*P_), Proxy, (void*)P_.Get(), 0, nullptr));
- #endif
-
+ #endif
+
if (!Handle) {
P_->UnRef();
ythrow yexception() << "failed to create a thread";
}
- }
-
- private:
- TParamsRef P_;
- HANDLE Handle;
- #if _WIN32_WINNT < 0x0502
- ui32 ThreadId;
- #endif
- };
-
+ }
+
+ private:
+ TParamsRef P_;
+ HANDLE Handle;
+ #if _WIN32_WINNT < 0x0502
+ ui32 ThreadId;
+ #endif
+ };
+
using TThreadBase = TWinThread;
#else
- //unix
-
- #define PCHECK(x, y) \
- { \
- const int err_ = x; \
- if (err_) { \
- ythrow TSystemError(err_) << TStringBuf(y); \
- } \
- }
-
- class TPosixThread {
- public:
- inline TPosixThread(const TParams& params)
- : P_(new TParams(params))
+ //unix
+
+ #define PCHECK(x, y) \
+ { \
+ const int err_ = x; \
+ if (err_) { \
+ ythrow TSystemError(err_) << TStringBuf(y); \
+ } \
+ }
+
+ class TPosixThread {
+ public:
+ inline TPosixThread(const TParams& params)
+ : P_(new TParams(params))
, H_()
- {
- static_assert(sizeof(H_) == sizeof(TId), "expect sizeof(H_) == sizeof(TId)");
- }
-
+ {
+ static_assert(sizeof(H_) == sizeof(TId), "expect sizeof(H_) == sizeof(TId)");
+ }
+
inline TId SystemThreadId() const noexcept {
- return (TId)H_;
- }
-
- inline void* Join() {
+ return (TId)H_;
+ }
+
+ inline void* Join() {
void* tec = nullptr;
- PCHECK(pthread_join(H_, &tec), "can not join thread");
-
- return tec;
- }
-
- inline void Detach() {
- PCHECK(pthread_detach(H_), "can not detach thread");
- }
-
+ PCHECK(pthread_join(H_, &tec), "can not join thread");
+
+ return tec;
+ }
+
+ inline void Detach() {
+ PCHECK(pthread_detach(H_), "can not detach thread");
+ }
+
inline bool Running() const noexcept {
- return (bool)H_;
- }
-
- inline void Start() {
+ return (bool)H_;
+ }
+
+ inline void Start() {
pthread_attr_t* pattrs = nullptr;
- pthread_attr_t attrs;
-
- if (P_->StackSize > 0) {
- Zero(attrs);
- pthread_attr_init(&attrs);
- pattrs = &attrs;
-
- if (P_->StackPointer) {
- pthread_attr_setstack(pattrs, P_->StackPointer, P_->StackSize);
- } else {
- pthread_attr_setstacksize(pattrs, StackSize(*P_));
- }
- }
-
+ pthread_attr_t attrs;
+
+ if (P_->StackSize > 0) {
+ Zero(attrs);
+ pthread_attr_init(&attrs);
+ pattrs = &attrs;
+
+ if (P_->StackPointer) {
+ pthread_attr_setstack(pattrs, P_->StackPointer, P_->StackSize);
+ } else {
+ pthread_attr_setstacksize(pattrs, StackSize(*P_));
+ }
+ }
+
{
- TParams* holdP = P_.Release();
+ TParams* holdP = P_.Release();
int err = pthread_create(&H_, pattrs, ThreadProxy, holdP);
if (err) {
H_ = {};
@@ -212,54 +212,54 @@ namespace {
PCHECK(err, "failed to create thread");
}
}
- }
-
- private:
- static void* ThreadProxy(void* arg) {
- THolder<TParams> p((TParams*)arg);
-
- SetThrName(*p);
-
- return p->Proc(p->Data);
- }
-
- private:
- THolder<TParams> P_;
- pthread_t H_;
- };
-
- #undef PCHECK
-
+ }
+
+ private:
+ static void* ThreadProxy(void* arg) {
+ THolder<TParams> p((TParams*)arg);
+
+ SetThrName(*p);
+
+ return p->Proc(p->Data);
+ }
+
+ private:
+ THolder<TParams> P_;
+ pthread_t H_;
+ };
+
+ #undef PCHECK
+
using TThreadBase = TPosixThread;
#endif
-
- template <class T>
- static inline typename T::TValueType* Impl(T& t, const char* op, bool check = true) {
- if (!t) {
- ythrow yexception() << "can not " << op << " dead thread";
- }
-
- if (t->Running() != check) {
- static const char* const msg[] = {"running", "not running"};
-
- ythrow yexception() << "can not " << op << " " << msg[check] << " thread";
- }
-
- return t.Get();
- }
-}
-
-class TThread::TImpl: public TThreadBase {
-public:
+
+ template <class T>
+ static inline typename T::TValueType* Impl(T& t, const char* op, bool check = true) {
+ if (!t) {
+ ythrow yexception() << "can not " << op << " dead thread";
+ }
+
+ if (t->Running() != check) {
+ static const char* const msg[] = {"running", "not running"};
+
+ ythrow yexception() << "can not " << op << " " << msg[check] << " thread";
+ }
+
+ return t.Get();
+ }
+}
+
+class TThread::TImpl: public TThreadBase {
+public:
inline TImpl(const TParams& params, THolder<TCallableBase> callable = {})
- : TThreadBase(params)
+ : TThreadBase(params)
, Callable_(std::move(callable))
- {
- }
-
+ {
+ }
+
inline TId Id() const noexcept {
- return ThreadIdHashFunction(SystemThreadId());
- }
+ return ThreadIdHashFunction(SystemThreadId());
+ }
static THolder<TImpl> Create(THolder<TCallableBase> callable) {
TParams params(TCallableBase::ThreadWorker, callable.Get());
@@ -268,18 +268,18 @@ public:
private:
THolder<TCallableBase> Callable_;
-};
-
-TThread::TThread(const TParams& p)
- : Impl_(new TImpl(p))
-{
+};
+
+TThread::TThread(const TParams& p)
+ : Impl_(new TImpl(p))
+{
+}
+
+TThread::TThread(TThreadProc threadProc, void* param)
+ : Impl_(new TImpl(TParams(threadProc, param)))
+{
}
-TThread::TThread(TThreadProc threadProc, void* param)
- : Impl_(new TImpl(TParams(threadProc, param)))
-{
-}
-
TThread::TThread(TPrivateCtor, THolder<TCallableBase> callable)
: Impl_(TImpl::Create(std::move(callable)))
{
@@ -287,13 +287,13 @@ TThread::TThread(TPrivateCtor, THolder<TCallableBase> callable)
TThread::~TThread() {
Join();
-}
-
+}
+
void TThread::Start() {
- Impl(Impl_, "start", false)->Start();
-}
-
-void* TThread::Join() {
+ Impl(Impl_, "start", false)->Start();
+}
+
+void* TThread::Join() {
if (Running()) {
void* ret = Impl_->Join();
@@ -301,33 +301,33 @@ void* TThread::Join() {
return ret;
}
-
+
return nullptr;
}
-void TThread::Detach() {
- if (Running()) {
- Impl_->Detach();
- Impl_.Destroy();
- }
-}
-
+void TThread::Detach() {
+ if (Running()) {
+ Impl_->Detach();
+ Impl_.Destroy();
+ }
+}
+
bool TThread::Running() const noexcept {
return Impl_ && Impl_->Running();
-}
-
+}
+
TThread::TId TThread::Id() const noexcept {
- if (Running()) {
- return Impl_->Id();
- }
-
- return ImpossibleThreadId();
-}
-
+ if (Running()) {
+ return Impl_->Id();
+ }
+
+ return ImpossibleThreadId();
+}
+
TThread::TId TThread::CurrentThreadId() noexcept {
- return SystemCurrentThreadId();
-}
-
+ return SystemCurrentThreadId();
+}
+
TThread::TId TThread::CurrentThreadNumericId() noexcept {
#if defined(_win_)
return GetCurrentThreadId();
@@ -353,61 +353,61 @@ TThread::TId TThread::CurrentThreadNumericId() noexcept {
}
TThread::TId TThread::ImpossibleThreadId() noexcept {
- return Max<TThread::TId>();
-}
+ return Max<TThread::TId>();
+}
namespace {
- template <class T>
+ template <class T>
static void* ThreadProcWrapper(void* param) {
- return reinterpret_cast<T*>(param)->ThreadProc();
- }
+ return reinterpret_cast<T*>(param)->ThreadProc();
+ }
}
ISimpleThread::ISimpleThread(size_t stackSize)
: TThread(TParams(ThreadProcWrapper<ISimpleThread>, reinterpret_cast<void*>(this), stackSize))
{
}
-
-#if defined(_MSC_VER)
- // This beautiful piece of code is borrowed from
- // http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
-
- //
- // Usage: WindowsCurrentSetThreadName (-1, "MainThread");
- //
- #include <windows.h>
- #include <processthreadsapi.h>
-
-const DWORD MS_VC_EXCEPTION = 0x406D1388;
-
- #pragma pack(push, 8)
-typedef struct tagTHREADNAME_INFO {
- DWORD dwType; // Must be 0x1000.
- LPCSTR szName; // Pointer to name (in user addr space).
- DWORD dwThreadID; // Thread ID (-1=caller thread).
- DWORD dwFlags; // Reserved for future use, must be zero.
-} THREADNAME_INFO;
- #pragma pack(pop)
-
-static void WindowsCurrentSetThreadName(DWORD dwThreadID, const char* threadName) {
- THREADNAME_INFO info;
- info.dwType = 0x1000;
- info.szName = threadName;
- info.dwThreadID = dwThreadID;
- info.dwFlags = 0;
-
- __try {
- RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- }
-}
-#endif
-
+
+#if defined(_MSC_VER)
+ // This beautiful piece of code is borrowed from
+ // http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
+
+ //
+ // Usage: WindowsCurrentSetThreadName (-1, "MainThread");
+ //
+ #include <windows.h>
+ #include <processthreadsapi.h>
+
+const DWORD MS_VC_EXCEPTION = 0x406D1388;
+
+ #pragma pack(push, 8)
+typedef struct tagTHREADNAME_INFO {
+ DWORD dwType; // Must be 0x1000.
+ LPCSTR szName; // Pointer to name (in user addr space).
+ DWORD dwThreadID; // Thread ID (-1=caller thread).
+ DWORD dwFlags; // Reserved for future use, must be zero.
+} THREADNAME_INFO;
+ #pragma pack(pop)
+
+static void WindowsCurrentSetThreadName(DWORD dwThreadID, const char* threadName) {
+ THREADNAME_INFO info;
+ info.dwType = 0x1000;
+ info.szName = threadName;
+ info.dwThreadID = dwThreadID;
+ info.dwFlags = 0;
+
+ __try {
+ RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
+ } __except (EXCEPTION_EXECUTE_HANDLER) {
+ }
+}
+#endif
+
#if defined(_win_)
namespace {
struct TWinThreadDescrAPI {
TWinThreadDescrAPI()
- : Kernel32Dll("kernel32.dll")
+ : Kernel32Dll("kernel32.dll")
, SetThreadDescription((TSetThreadDescription)Kernel32Dll.SymOptional("SetThreadDescription"))
, GetThreadDescription((TGetThreadDescription)Kernel32Dll.SymOptional("GetThreadDescription"))
{
@@ -435,8 +435,8 @@ namespace {
return WideToUTF8((const wchar16*)wideName);
}
- typedef HRESULT(__cdecl* TSetThreadDescription)(HANDLE hThread, PCWSTR lpThreadDescription);
- typedef HRESULT(__cdecl* TGetThreadDescription)(HANDLE hThread, PWSTR* ppszThreadDescription);
+ typedef HRESULT(__cdecl* TSetThreadDescription)(HANDLE hThread, PCWSTR lpThreadDescription);
+ typedef HRESULT(__cdecl* TGetThreadDescription)(HANDLE hThread, PWSTR* ppszThreadDescription);
TDynamicLibrary Kernel32Dll;
TSetThreadDescription SetThreadDescription;
@@ -446,29 +446,29 @@ namespace {
#endif // _win_
void TThread::SetCurrentThreadName(const char* name) {
- (void)name;
-
-#if defined(_freebsd_)
- pthread_t thread = pthread_self();
+ (void)name;
+
+#if defined(_freebsd_)
+ pthread_t thread = pthread_self();
pthread_set_name_np(thread, name);
-#elif defined(_linux_)
+#elif defined(_linux_)
prctl(PR_SET_NAME, name, 0, 0, 0);
-#elif defined(_darwin_)
+#elif defined(_darwin_)
pthread_setname_np(name);
#elif defined(_win_)
auto api = Singleton<TWinThreadDescrAPI>();
if (api->HasAPI()) {
api->SetDescr(name);
} else {
- #if defined(_MSC_VER)
+ #if defined(_MSC_VER)
WindowsCurrentSetThreadName(DWORD(-1), name);
- #endif
+ #endif
}
-#else
-// no idea
-#endif // OS
-}
-
+#else
+// no idea
+#endif // OS
+}
+
TString TThread::CurrentThreadName() {
#if defined(_freebsd_)
// TODO: check pthread_get_name_np API availability
@@ -494,7 +494,7 @@ TString TThread::CurrentThreadName() {
}
return {};
#else
-// no idea
+// no idea
#endif // OS
return {};
@@ -510,37 +510,37 @@ bool TThread::CanGetCurrentThreadName() {
#endif // OS
}
-TCurrentThreadLimits::TCurrentThreadLimits() noexcept
- : StackBegin(nullptr)
- , StackLength(0)
-{
+TCurrentThreadLimits::TCurrentThreadLimits() noexcept
+ : StackBegin(nullptr)
+ , StackLength(0)
+{
#if defined(_linux_) || defined(_cygwin_) || defined(_freebsd_)
- pthread_attr_t attr;
- pthread_attr_init(&attr);
-
- #if defined(_linux_) || defined(_cygwin_)
- Y_VERIFY(pthread_getattr_np(pthread_self(), &attr) == 0, "pthread_getattr failed");
- #else
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+
+ #if defined(_linux_) || defined(_cygwin_)
+ Y_VERIFY(pthread_getattr_np(pthread_self(), &attr) == 0, "pthread_getattr failed");
+ #else
Y_VERIFY(pthread_attr_get_np(pthread_self(), &attr) == 0, "pthread_attr_get_np failed");
- #endif
- pthread_attr_getstack(&attr, (void**)&StackBegin, &StackLength);
- pthread_attr_destroy(&attr);
-
-#elif defined(_darwin_)
- StackBegin = pthread_get_stackaddr_np(pthread_self());
- StackLength = pthread_get_stacksize_np(pthread_self());
-#elif defined(_MSC_VER)
-
- #if _WIN32_WINNT >= _WIN32_WINNT_WIN8
- ULONG_PTR b = 0;
- ULONG_PTR e = 0;
-
+ #endif
+ pthread_attr_getstack(&attr, (void**)&StackBegin, &StackLength);
+ pthread_attr_destroy(&attr);
+
+#elif defined(_darwin_)
+ StackBegin = pthread_get_stackaddr_np(pthread_self());
+ StackLength = pthread_get_stacksize_np(pthread_self());
+#elif defined(_MSC_VER)
+
+ #if _WIN32_WINNT >= _WIN32_WINNT_WIN8
+ ULONG_PTR b = 0;
+ ULONG_PTR e = 0;
+
GetCurrentThreadStackLimits(&b, &e);
-
- StackBegin = (const void*)b;
- StackLength = e - b;
- #else
+ StackBegin = (const void*)b;
+ StackLength = e - b;
+
+ #else
// Copied from https://github.com/llvm-mirror/compiler-rt/blob/release_40/lib/sanitizer_common/sanitizer_win.cc#L91
void* place_on_stack = alloca(16);
MEMORY_BASIC_INFORMATION memory_info;
@@ -549,9 +549,9 @@ TCurrentThreadLimits::TCurrentThreadLimits() noexcept
StackBegin = memory_info.AllocationBase;
StackLength = static_cast<const char*>(memory_info.BaseAddress) + memory_info.RegionSize - static_cast<const char*>(StackBegin);
- #endif
+ #endif
-#else
- #error port me
-#endif
-}
+#else
+ #error port me
+#endif
+}