summaryrefslogtreecommitdiff
path: root/src/common/std_thread.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/std_thread.h')
-rw-r--r--src/common/std_thread.h314
1 files changed, 0 insertions, 314 deletions
diff --git a/src/common/std_thread.h b/src/common/std_thread.h
deleted file mode 100644
index ce1336ee7..000000000
--- a/src/common/std_thread.h
+++ /dev/null
@@ -1,314 +0,0 @@
1#pragma once
2
3#define GCC_VER(x,y,z) ((x) * 10000 + (y) * 100 + (z))
4#define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
5
6#ifndef __has_include
7#define __has_include(s) 0
8#endif
9
10#if GCC_VERSION >= GCC_VER(4,4,0) && __GXX_EXPERIMENTAL_CXX0X__
11// GCC 4.4 provides <thread>
12#ifndef _GLIBCXX_USE_SCHED_YIELD
13#define _GLIBCXX_USE_SCHED_YIELD
14#endif
15#include <thread>
16#elif __has_include(<thread>) && !ANDROID
17// Clang + libc++
18#include <thread>
19#else
20
21// partial std::thread implementation for win32/pthread
22
23#include <algorithm>
24
25#if (_MSC_VER >= 1600) || (GCC_VERSION >= GCC_VER(4,3,0) && __GXX_EXPERIMENTAL_CXX0X__)
26#define USE_RVALUE_REFERENCES
27#endif
28
29#ifdef __APPLE__
30#import <Foundation/NSAutoreleasePool.h>
31#endif
32
33#if defined(_WIN32)
34// WIN32
35
36#define WIN32_LEAN_AND_MEAN
37#include <Windows.h>
38
39#if defined(_MSC_VER) && defined(_MT)
40// When linking with LIBCMT (the multithreaded C library), Microsoft recommends
41// using _beginthreadex instead of CreateThread.
42#define USE_BEGINTHREADEX
43#include <process.h>
44#endif
45
46#ifdef USE_BEGINTHREADEX
47#define THREAD_ID unsigned
48#define THREAD_RETURN unsigned __stdcall
49#else
50#define THREAD_ID DWORD
51#define THREAD_RETURN DWORD WINAPI
52#endif
53#define THREAD_HANDLE HANDLE
54
55#else
56// PTHREAD
57
58#include <unistd.h>
59
60#ifndef _POSIX_THREADS
61#error unsupported platform (no pthreads?)
62#endif
63
64#include <pthread.h>
65
66#define THREAD_ID pthread_t
67#define THREAD_HANDLE pthread_t
68#define THREAD_RETURN void*
69
70#endif
71
72namespace std
73{
74
75class thread
76{
77public:
78 typedef THREAD_HANDLE native_handle_type;
79
80 class id
81 {
82 friend class thread;
83 public:
84 id() : m_thread(0) {}
85 id(THREAD_ID _id) : m_thread(_id) {}
86
87 bool operator==(const id& rhs) const
88 {
89 return m_thread == rhs.m_thread;
90 }
91
92 bool operator!=(const id& rhs) const
93 {
94 return !(*this == rhs);
95 }
96
97 bool operator<(const id& rhs) const
98 {
99 return m_thread < rhs.m_thread;
100 }
101
102 private:
103 THREAD_ID m_thread;
104 };
105
106 // no variadic template support in msvc
107 //template <typename C, typename... A>
108 //thread(C&& func, A&&... args);
109
110 template <typename C>
111 thread(C func)
112 {
113 StartThread(new Func<C>(func));
114 }
115
116 template <typename C, typename A>
117 thread(C func, A arg)
118 {
119 StartThread(new FuncArg<C, A>(func, arg));
120 }
121
122 thread() /*= default;*/ {}
123
124#ifdef USE_RVALUE_REFERENCES
125 thread(const thread&) /*= delete*/;
126
127 thread(thread&& other)
128 {
129#else
130 thread(const thread& t)
131 {
132 // ugly const_cast to get around lack of rvalue references
133 thread& other = const_cast<thread&>(t);
134#endif
135 swap(other);
136 }
137
138#ifdef USE_RVALUE_REFERENCES
139 thread& operator=(const thread&) /*= delete*/;
140
141 thread& operator=(thread&& other)
142 {
143#else
144 thread& operator=(const thread& t)
145 {
146 // ugly const_cast to get around lack of rvalue references
147 thread& other = const_cast<thread&>(t);
148#endif
149 if (joinable())
150 detach();
151 swap(other);
152 return *this;
153 }
154
155 ~thread()
156 {
157 if (joinable())
158 detach();
159 }
160
161 bool joinable() const
162 {
163 return m_id != id();
164 }
165
166 id get_id() const
167 {
168 return m_id;
169 }
170
171 native_handle_type native_handle()
172 {
173#ifdef _WIN32
174 return m_handle;
175#else
176 return m_id.m_thread;
177#endif
178 }
179
180 void join()
181 {
182#ifdef _WIN32
183 WaitForSingleObject(m_handle, INFINITE);
184 detach();
185#else
186 pthread_join(m_id.m_thread, NULL);
187 m_id = id();
188#endif
189 }
190
191 void detach()
192 {
193#ifdef _WIN32
194 CloseHandle(m_handle);
195#else
196 pthread_detach(m_id.m_thread);
197#endif
198 m_id = id();
199 }
200
201 void swap(thread& other)
202 {
203 std::swap(m_id, other.m_id);
204#ifdef _WIN32
205 std::swap(m_handle, other.m_handle);
206#endif
207 }
208
209 static unsigned hardware_concurrency()
210 {
211#ifdef _WIN32
212 SYSTEM_INFO sysinfo;
213 GetSystemInfo(&sysinfo);
214 return static_cast<unsigned>(sysinfo.dwNumberOfProcessors);
215#else
216 return 0;
217#endif
218 }
219
220private:
221 id m_id;
222
223#ifdef _WIN32
224 native_handle_type m_handle;
225#endif
226
227 template <typename F>
228 void StartThread(F* param)
229 {
230#ifdef USE_BEGINTHREADEX
231 m_handle = (HANDLE)_beginthreadex(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread);
232#elif defined(_WIN32)
233 m_handle = CreateThread(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread);
234#else
235 pthread_attr_t attr;
236 pthread_attr_init(&attr);
237 pthread_attr_setstacksize(&attr, 1024 * 1024);
238 if (pthread_create(&m_id.m_thread, &attr, &RunAndDelete<F>, param))
239 m_id = id();
240#endif
241 }
242
243 template <typename C>
244 class Func
245 {
246 public:
247 Func(C _func) : func(_func) {}
248
249 void Run() { func(); }
250
251 private:
252 C const func;
253 };
254
255 template <typename C, typename A>
256 class FuncArg
257 {
258 public:
259 FuncArg(C _func, A _arg) : func(_func), arg(_arg) {}
260
261 void Run() { func(arg); }
262
263 private:
264 C const func;
265 A arg;
266 };
267
268 template <typename F>
269 static THREAD_RETURN RunAndDelete(void* param)
270 {
271#ifdef __APPLE__
272 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
273#endif
274 static_cast<F*>(param)->Run();
275 delete static_cast<F*>(param);
276#ifdef __APPLE__
277 [pool release];
278#endif
279 return 0;
280 }
281};
282
283namespace this_thread
284{
285
286inline void yield()
287{
288#ifdef _WIN32
289 SwitchToThread();
290#else
291 sleep(0);
292#endif
293}
294
295inline thread::id get_id()
296{
297#ifdef _WIN32
298 return GetCurrentThreadId();
299#else
300 return pthread_self();
301#endif
302}
303
304} // namespace this_thread
305
306} // namespace std
307
308#undef USE_RVALUE_REFERENCES
309#undef USE_BEGINTHREADEX
310#undef THREAD_ID
311#undef THREAD_RETURN
312#undef THREAD_HANDLE
313
314#endif