UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
UnixPlatformTLS.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3/*=============================================================================================
4 UnixPlatformTLS.h: Unix platform TLS (Thread local storage and thread ID) functions
5==============================================================================================*/
6
7#pragma once
8
9#include "CoreTypes.h"
10#include "Unix/UnixSystemIncludes.h" // IWYU pragma: export
13
14#if defined(_GNU_SOURCE)
15 #include <sys/syscall.h>
16#endif // _GNU_SOURCE
17
22{
26 static inline uint32 GetCurrentThreadId(void)
27 {
28 // note: cannot use pthread_self() without updating the rest of API to opaque (or at least 64-bit) thread handles
29#if defined(_GNU_SOURCE)
30
31 // syscall() is relatively heavy and the whole editor grinds to a halt.
32 // Cache thread id in TLS, but allocate TLS slots dynamically for non-monolithic case since limit on dynamic libs with static per-thread variables (DTV_SURPLUS) is low
33 #if !IS_MONOLITHIC
34 uint32 ThreadIdTLS = static_cast<uint32>(reinterpret_cast<UPTRINT>(GetTlsValue(ThreadIdTLSKey)));
35 #endif
36 if (UNLIKELY(ThreadIdTLS == 0))
37 {
38 pid_t ThreadId = static_cast<pid_t>(syscall(SYS_gettid));
39 static_assert(sizeof(pid_t) <= sizeof(uint32), "pid_t is larger than uint32, reconsider implementation of GetCurrentThreadId()");
40 ThreadIdTLS = static_cast<uint32>(ThreadId);
41 checkf(ThreadIdTLS != 0, TEXT("ThreadId is 0 - reconsider implementation of GetCurrentThreadId() (syscall changed?)"));
42
43 #if !IS_MONOLITHIC
44 SetTlsValue(ThreadIdTLSKey, reinterpret_cast<void *>(static_cast<UPTRINT>(ThreadIdTLS)));
45 #endif
46 }
47 return ThreadIdTLS;
48
49#else
50 // better than nothing...
51 static_assert(sizeof(uint32) == sizeof(pthread_t), "pthread_t cannot be converted to uint32 one to one - different number of bits. Review FUnixTLS::GetCurrentThreadId() implementation.");
52 return static_cast< uint32 >(pthread_self());
53#endif
54 }
55
56 static void ClearThreadIdTLS(void)
57 {
58#if IS_MONOLITHIC
59 ThreadIdTLS = 0;
60#else
61 SetTlsValue(ThreadIdTLSKey, nullptr);
62#endif
63 }
64
68 static uint32 AllocTlsSlot(void)
69 {
70 // allocate a per-thread mem slot
71 pthread_key_t Key = 0;
72 if (pthread_key_create(&Key, nullptr) != 0)
73 {
74 return static_cast<uint32>(INDEX_NONE); // matches the Windows TlsAlloc() retval.
75 }
76
77 // pthreads can return an arbitrary key, yet we reserve INDEX_NONE as an invalid one. Handle this very unlikely case
78 // by allocating another one first (so we get another value) and releasing existing key.
79 if (static_cast<uint32>(Key) == static_cast<uint32>(INDEX_NONE))
80 {
81 pthread_key_t NewKey = 0;
82 int SecondKeyAllocResult = pthread_key_create(&NewKey, nullptr);
83 // discard the previous one
85
86 if (SecondKeyAllocResult != 0)
87 {
88 // could not alloc the second key, treat this as an error
89 return static_cast<uint32>(INDEX_NONE); // matches the Windows TlsAlloc() retval.
90 }
91
92 // check that we indeed got something different
93 checkf(NewKey != static_cast<uint32>(INDEX_NONE), TEXT("Could not allocate a usable TLS slot id."));
94
95 Key = NewKey;
96 }
97
98 return Key;
99 }
100
107 static UE_FORCEINLINE_HINT void SetTlsValue(uint32 SlotIndex,void* Value)
108 {
110 }
111
117 static UE_FORCEINLINE_HINT void* GetTlsValue(uint32 SlotIndex)
118 {
119 return pthread_getspecific((pthread_key_t)SlotIndex);
120 }
121
128 {
130 }
131
132private:
133
134#if IS_MONOLITHIC
137#else
139 static CORE_API uint32 ThreadIdTLSKey;
140#endif
141};
142
#define checkf(expr, format,...)
Definition AssertionMacros.h:315
@ INDEX_NONE
Definition CoreMiscDefines.h:150
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::UPTRINT UPTRINT
An unsigned integer the same size as a pointer.
Definition Platform.h:1146
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
#define UNLIKELY(x)
Definition Platform.h:857
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
FUnixTLS FPlatformTLS
Definition UnixPlatformTLS.h:143
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition GenericPlatformTLS.h:12
Definition UnixPlatformTLS.h:22
static void ClearThreadIdTLS(void)
Definition UnixPlatformTLS.h:56
static uint32 GetCurrentThreadId(void)
Definition UnixPlatformTLS.h:26
static UE_FORCEINLINE_HINT void SetTlsValue(uint32 SlotIndex, void *Value)
Definition UnixPlatformTLS.h:107
static UE_FORCEINLINE_HINT void FreeTlsSlot(uint32 SlotIndex)
Definition UnixPlatformTLS.h:127
static uint32 AllocTlsSlot(void)
Definition UnixPlatformTLS.h:68
static UE_FORCEINLINE_HINT void * GetTlsValue(uint32 SlotIndex)
Definition UnixPlatformTLS.h:117