summaryrefslogtreecommitdiffstats
path: root/library/cpp/yt/system/thread_id.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'library/cpp/yt/system/thread_id.cpp')
-rw-r--r--library/cpp/yt/system/thread_id.cpp28
1 files changed, 26 insertions, 2 deletions
diff --git a/library/cpp/yt/system/thread_id.cpp b/library/cpp/yt/system/thread_id.cpp
index a1971dd0dd8..978c735df25 100644
--- a/library/cpp/yt/system/thread_id.cpp
+++ b/library/cpp/yt/system/thread_id.cpp
@@ -2,19 +2,43 @@
#include <util/system/thread.h>
+#ifdef _unix_
+#include <library/cpp/yt/misc/static_initializer.h>
+
+#include <pthread.h>
+#endif
+
namespace NYT {
////////////////////////////////////////////////////////////////////////////////
+YT_DEFINE_THREAD_LOCAL(TSystemThreadId, CachedSystemThreadId, InvalidSystemThreadId);
+
YT_DEFINE_THREAD_LOCAL(TSequentialThreadId, CachedSequentialThreadId, InvalidSequentialThreadId);
std::atomic<TSequentialThreadId> SequentialThreadIdGenerator = InvalidSequentialThreadId;
-TSystemThreadId GetSystemThreadId()
+namespace NDetail {
+
+TSystemThreadId GetSystemThreadIdImpl()
{
static_assert(std::is_same_v<TSystemThreadId, ::TThread::TId>);
return ::TThread::CurrentThreadNumericId();
}
+} // namespace NDetail
+
+#ifdef _unix_
+// The kernel tid is stable for the lifetime of a thread, so we cache it to
+// avoid the |gettid| syscall on each call. After a |fork|, however, the
+// surviving (calling) thread of the child gets a fresh kernel tid, so the
+// cache must be invalidated there.
+YT_STATIC_INITIALIZER(
+ ::pthread_atfork(
+ /*prepare*/ nullptr,
+ /*parent*/ nullptr,
+ /*child*/ [] { CachedSystemThreadId() = InvalidSystemThreadId; }));
+#endif
+
////////////////////////////////////////////////////////////////////////////////
-} // namespace NYT::NThreading
+} // namespace NYT