LLVM: include/llvm/Support/thread.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#ifndef LLVM_SUPPORT_THREAD_H
17#define LLVM_SUPPORT_THREAD_H
18
19#include "llvm/Config/llvm-config.h"
21#include
22#include
23#include
24
25#ifdef _WIN32
26typedef unsigned long DWORD;
27typedef void *PVOID;
28typedef PVOID HANDLE;
29#endif
30
31#if LLVM_ENABLE_THREADS
32
33#include
34
35namespace llvm {
36
37#if defined(LLVM_ON_UNIX) || defined(_WIN32)
38
39
40
42 template static void GenericThreadProxy(void *Ptr) {
43 std::unique_ptr Callee(static_cast<CalleeTuple *>(Ptr));
44 std::apply(
45 [](auto &&F, auto &&...Args) {
46 std::forward<decltype(F)>(F)(std::forward<decltype(Args)>(Args)...);
47 },
49 }
50
51public:
52#ifdef LLVM_ON_UNIX
53 using native_handle_type = pthread_t;
54 using id = pthread_t;
55 using start_routine_type = void *(*)(void *);
56
57 template static void *ThreadProxy(void *Ptr) {
58 GenericThreadProxy(Ptr);
59 return nullptr;
60 }
61#elif _WIN32
62 using native_handle_type = HANDLE;
64 using start_routine_type = unsigned(__stdcall *)(void *);
65
66 template
67 static unsigned __stdcall ThreadProxy(void *Ptr) {
68 GenericThreadProxy(Ptr);
69 return 0;
70 }
71#endif
72
73 LLVM_ABI static const std::optional DefaultStackSize;
74
77 : Thread(std::exchange(Other.Thread, native_handle_type())) {}
78
80 explicit thread(Function &&f, Args &&...args)
82
84 explicit thread(std::optional StackSizeInBytes, Function &&f,
85 Args &&...args);
87
89 if (joinable())
90 std::terminate();
91 }
92
94 if (joinable())
95 std::terminate();
96 Thread = std::exchange(Other.Thread, native_handle_type());
97 return *this;
98 }
99
100 bool joinable() const noexcept { return Thread != native_handle_type(); }
101
102 inline id get_id() const noexcept;
103
104 native_handle_type native_handle() const noexcept { return Thread; }
105
107 return std::thread::hardware_concurrency();
108 };
109
110 inline void join();
111 inline void detach();
112
114
115private:
116 native_handle_type Thread;
117};
118
119LLVM_ABI thread::native_handle_type
120llvm_execute_on_thread_impl(thread::start_routine_type ThreadFunc, void *Arg,
121 std::optional StackSizeInBytes);
122LLVM_ABI void llvm_thread_join_impl(thread::native_handle_type Thread);
123LLVM_ABI void llvm_thread_detach_impl(thread::native_handle_type Thread);
124LLVM_ABI thread::id llvm_thread_get_id_impl(thread::native_handle_type Thread);
125LLVM_ABI thread::id llvm_thread_get_current_id_impl();
126
129 Args &&...args) {
130 using CalleeTuple = std::tuple<std::decay_t, std::decay_t...>;
131 std::unique_ptr Callee(
132 new CalleeTuple(std::forward(f), std::forward(args)...));
133
134 Thread = llvm_execute_on_thread_impl(ThreadProxy, Callee.get(),
135 StackSizeInBytes);
136 if (Thread != native_handle_type())
138}
139
140thread::id thread::get_id() const noexcept {
141 return llvm_thread_get_id_impl(Thread);
142}
143
145 llvm_thread_join_impl(Thread);
146 Thread = native_handle_type();
147}
148
150 llvm_thread_detach_impl(Thread);
151 Thread = native_handle_type();
152}
153
154namespace this_thread {
155inline thread::id get_id() { return llvm_thread_get_current_id_impl(); }
156}
157
158#else
159
160
161
163public:
164 using native_handle_type = std::thread::native_handle_type;
165 using id = std::thread::id;
166
169 : Thread(std::exchange(Other.Thread, std::thread())) {}
170
172 explicit thread(std::optional StackSizeInBytes, Function &&f,
173 Args &&...args)
175
178
180
182
184 Thread = std::exchange(Other.Thread, std::thread());
185 return *this;
186 }
187
188 bool joinable() const noexcept { return Thread.joinable(); }
189
190 id get_id() const noexcept { return Thread.get_id(); }
191
192 native_handle_type native_handle() noexcept { return Thread.native_handle(); }
193
195 return std::thread::hardware_concurrency();
196 };
197
198 inline void join() { Thread.join(); }
200
202
203private:
205};
206
207namespace this_thread {
208inline thread::id get_id() { return std::this_thread::get_id(); }
209}
210
211#endif
212
213}
214
215#else
216
218#include
219
220namespace llvm {
221
225 template <class Function, class... Args>
226 explicit thread(std::optional StackSizeInBytes, Function &&f,
227 Args &&...args) {
228 f(std::forward(args)...);
229 }
230 template <class Function, class... Args>
232 f(std::forward(args)...);
233 }
235
237 report_fatal_error("Detaching from a thread does not make sense with no "
238 "threading support");
239 }
242};
243
244}
245
246#endif
247
248#endif
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
thread(std::optional< unsigned > StackSizeInBytes, Function &&f, Args &&...args)
Definition thread.h:226
static unsigned hardware_concurrency()
Definition thread.h:241
void join()
Definition thread.h:240
thread(Function &&f, Args &&...args)
Definition thread.h:231
thread(const thread &)=delete
thread(thread &&other)
Definition thread.h:224
thread()
Definition thread.h:223
void detach()
Definition thread.h:236