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