ReXGlue SDK
Loading...
Searching...
No Matches
thread.h
Go to the documentation of this file.
1
12
13#pragma once
14
15#include <algorithm>
16#include <atomic>
17#include <chrono>
18#include <climits>
19#include <cstddef>
20#include <cstdint>
21#include <memory>
22#include <stop_token>
23#include <string>
24#include <string_view>
25#include <thread>
26#include <utility>
27#include <vector>
28
29#include <rex/assert.h>
30#include <rex/platform.h>
32#include <rex/platform/sync.h>
33#include <rex/types.h>
34#include <rex/utility.h>
35
36namespace rex::platform {
37
38#if REX_PLATFORM_ANDROID
40REX_API void AndroidInitialize();
42REX_API void AndroidShutdown();
43#endif
44
45REX_API u32 GetLogicalProcessorCount();
46
49
52
58
61
67REX_API void SetCurrentThreadName(const std::string_view name);
68
76
79
82
84REX_API void SleepFor(std::chrono::microseconds duration);
85
86template <typename Rep, typename Period>
87void SleepFor(std::chrono::duration<Rep, Period> duration) {
88 SleepFor(std::chrono::duration_cast<std::chrono::microseconds>(duration));
89}
90
92REX_API std::chrono::milliseconds GetCurrentThreadCPUTime();
93
95enum class SleepResult : u8 {
96 kSuccess,
98};
99
105REX_API SleepResult AlertableSleep(std::chrono::microseconds duration);
106
112template <typename Rep, typename Period>
113SleepResult AlertableSleep(std::chrono::duration<Rep, Period> duration) {
114 return AlertableSleep(std::chrono::duration_cast<std::chrono::microseconds>(duration));
115}
116
117using TLSHandle = u32;
118constexpr TLSHandle kInvalidTLSHandle = UINT_MAX;
119
120REX_API TLSHandle AllocateTLSHandle();
121
122REX_API bool FreeTLSHandle(TLSHandle handle);
123
129REX_API uintptr_t GetTLSValue(TLSHandle handle);
130
132REX_API bool SetTLSValue(TLSHandle handle, uintptr_t value);
133
134#if REX_PLATFORM_WIN32
136struct ThreadPriority {
137 static const i32 kLowest = -2;
138 static const i32 kBelowNormal = -1;
139 static const i32 kNormal = 0;
140 static const i32 kAboveNormal = 1;
141 static const i32 kHighest = 2;
142};
143#else
146 static const i32 kLowest = 1;
147 static const i32 kBelowNormal = 8;
148 static const i32 kNormal = 16;
149 static const i32 kAboveNormal = 24;
150 static const i32 kHighest = 32;
151};
152#endif
153
155class REX_API Thread : public WaitHandle {
156 public:
158 size_t stack_size = 4_MiB;
159 bool create_suspended = false;
161 };
162
168 static std::unique_ptr<Thread> Create(CreationParameters params,
169 rex::MoveOnlyFunction<void()> start_routine);
174
179 static void Exit(int exit_code);
180
181 virtual u32 GetSystemID() const = 0;
182
183 const std::string& GetName() const { return name_; }
184
186 virtual void SetName(std::string name) { name_ = std::move(name); }
187
188 virtual i32 GetPriority() = 0;
189
195 virtual void SetPriority(i32 new_priority) = 0;
196
201 virtual u64 GetAffinityMask() = 0;
202
208 virtual void SetAffinityMask(u64 new_affinity_mask) = 0;
209
214 virtual void QueueUserCallback(rex::MoveOnlyFunction<void()> callback) = 0;
215
221 virtual bool Resume(u32* out_previous_suspend_count = nullptr) = 0;
222
228 virtual bool Suspend(u32* out_previous_suspend_count = nullptr) = 0;
229
236 using RedirectFilter = bool (*)(u64 pc, void* context);
237
246 virtual bool Redirect(RedirectFilter filter, void* context, void (*target)()) = 0;
247
255 virtual bool SuspendIf(RedirectFilter filter, void* context) = 0;
256
257 protected:
258 std::string name_;
259};
260
261namespace detail {
262
264REX_API void RegisterCurrentThread();
265
269REX_API u64 GetThreadCount();
270
271} // namespace detail
272
280template <typename F>
281std::jthread Spawn(std::string_view name, F&& fn) {
282 return std::jthread([thread_name = std::string(name),
283 body = std::forward<F>(fn)](const std::stop_token& token) mutable {
284 detail::RegisterCurrentThread();
286 SetCurrentThreadName(thread_name);
287 body(std::move(token));
288 });
289}
290
291} // namespace rex::platform
292
293#if REX_PLATFORM_LINUX || REX_PLATFORM_MAC
294#if REX_PLATFORM_MAC && !defined(_XOPEN_SOURCE)
295#define _XOPEN_SOURCE 700
296#endif
297#include <ucontext.h>
298#include <cstdint>
299#include <vector>
300#endif
301
302namespace rex::platform {
303
314
320 static Fiber* Create(size_t stack_size, void (*entry)(void*), void* arg);
321
323 static void SwitchTo(Fiber* target);
324
329 void Destroy();
330
334 static Fiber* GetCurrent();
335
336 private:
337#if REX_PLATFORM_WIN32
338 void* handle_ = nullptr;
339 bool is_thread_fiber_ = false;
340#elif REX_PLATFORM_LINUX || REX_PLATFORM_MAC
341 ucontext_t context_{};
342 std::vector<u8> stack_;
343 void (*entry_)(void*) = nullptr;
344 void* arg_ = nullptr;
345 bool is_thread_fiber_ = false;
346
347 static void Trampoline();
348#endif
349};
350
351} // namespace rex::platform
352
353namespace rex {
354
357 i32 exit_code = 0;
358};
359
360} // namespace rex
Definition thread.h:155
static std::unique_ptr< Thread > Create(CreationParameters params, rex::MoveOnlyFunction< void()> start_routine)
virtual bool Redirect(RedirectFilter filter, void *context, void(*target)())=0
virtual bool Suspend(u32 *out_previous_suspend_count=nullptr)=0
virtual void SetPriority(i32 new_priority)=0
virtual bool Resume(u32 *out_previous_suspend_count=nullptr)=0
virtual u64 GetAffinityMask()=0
virtual void SetName(std::string name)
Definition thread.h:186
bool(*)(u64 pc, void *context) RedirectFilter
Definition thread.h:236
static Thread * GetCallingThread()
virtual bool SuspendIf(RedirectFilter filter, void *context)=0
virtual void QueueUserCallback(rex::MoveOnlyFunction< void()> callback)=0
static void Exit(int exit_code)
virtual void SetAffinityMask(u64 new_affinity_mask)=0
Definition platform.h:345
bool SetTLSValue(TLSHandle handle, uintptr_t value)
u32 GetCallerSystemThreadID()
void SetCurrentThreadName(const std::string_view name)
SleepResult
Definition thread.h:95
@ kAlerted
Definition thread.h:97
std::chrono::milliseconds GetCurrentThreadCPUTime()
void SleepFor(std::chrono::microseconds duration)
void PrepareThreadForCrash()
u32 GetCallerThreadID()
void MaybeYield()
SleepResult AlertableSleep(std::chrono::microseconds duration)
void SyncMemory()
uintptr_t GetTLSValue(TLSHandle handle)
void SetCallerThreadID(u32 id)
void WidenProcessAffinity()
std::jthread Spawn(std::string_view name, F &&fn)
Definition thread.h:281
void SetCurrentThreadPriority(i32 priority)
Definition app.h:36
typename detail::MoveOnlyFunctionFor< Signature >::type MoveOnlyFunction
Definition utility.h:254
Platform flags, packing macros and export markers.
#define REX_API
Definition platform.h:177
Process control, console, environment and crash reports.
Definition thread.h:356
Definition thread.h:307
static Fiber * ConvertCurrentThread()
static void SwitchTo(Fiber *target)
static Fiber * Create(size_t stack_size, void(*entry)(void *), void *arg)
static Fiber * GetCurrent()
Definition thread.h:145
i32 initial_priority
Definition thread.h:160
bool create_suspended
Definition thread.h:159
Wait objects and wait functions.
Integer types, byte order wrappers and size literals.
Move only function, const propagating pointer and scope guard.