]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/thread/win32/thread_primitives.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / thread / win32 / thread_primitives.hpp
CommitLineData
7c673cae
FG
1#ifndef BOOST_WIN32_THREAD_PRIMITIVES_HPP
2#define BOOST_WIN32_THREAD_PRIMITIVES_HPP
3
4// win32_thread_primitives.hpp
5//
6// (C) Copyright 2005-7 Anthony Williams
7// (C) Copyright 2007 David Deakins
8//
9// Distributed under the Boost Software License, Version 1.0. (See
10// accompanying file LICENSE_1_0.txt or copy at
11// http://www.boost.org/LICENSE_1_0.txt)
12
13#include <boost/thread/detail/config.hpp>
14#include <boost/predef/platform.h>
15#include <boost/throw_exception.hpp>
16#include <boost/assert.hpp>
17#include <boost/thread/exceptions.hpp>
18#include <boost/detail/interlocked.hpp>
b32b8144 19
11fdf7f2
TL
20#include <boost/winapi/config.hpp>
21#include <boost/winapi/basic_types.hpp>
22#include <boost/winapi/semaphore.hpp>
23#include <boost/winapi/system.hpp>
24#include <boost/winapi/event.hpp>
25#include <boost/winapi/thread.hpp>
26#include <boost/winapi/get_current_thread.hpp>
27#include <boost/winapi/get_current_thread_id.hpp>
28#include <boost/winapi/get_current_process.hpp>
29#include <boost/winapi/get_current_process_id.hpp>
30#include <boost/winapi/wait.hpp>
31#include <boost/winapi/handles.hpp>
32#include <boost/winapi/access_rights.hpp>
33
34//#include <boost/winapi/synchronization.hpp>
b32b8144 35#include <boost/thread/win32/interlocked_read.hpp>
7c673cae
FG
36#include <algorithm>
37
38#if BOOST_PLAT_WINDOWS_RUNTIME
39#include <thread>
40#endif
41
7c673cae
FG
42namespace boost
43{
44 namespace detail
45 {
46 namespace win32
47 {
11fdf7f2
TL
48 typedef ::boost::winapi::HANDLE_ handle;
49 typedef ::boost::winapi::SYSTEM_INFO_ system_info;
50 typedef ::boost::winapi::ULONGLONG_ ticks_type;
51 unsigned const infinite=::boost::winapi::INFINITE_;
52 unsigned const timeout=::boost::winapi::WAIT_TIMEOUT_;
53 handle const invalid_handle_value=::boost::winapi::INVALID_HANDLE_VALUE_;
54 unsigned const event_modify_state=::boost::winapi::EVENT_MODIFY_STATE_;
55 unsigned const synchronize=::boost::winapi::SYNCHRONIZE_;
56 unsigned const wait_abandoned=::boost::winapi::WAIT_ABANDONED_;
7c673cae
FG
57 unsigned const create_event_initial_set = 0x00000002;
58 unsigned const create_event_manual_reset = 0x00000001;
11fdf7f2
TL
59 unsigned const event_all_access = ::boost::winapi::EVENT_ALL_ACCESS_;
60 unsigned const semaphore_all_access = boost::winapi::SEMAPHORE_ALL_ACCESS_;
7c673cae
FG
61 }
62 }
63}
7c673cae
FG
64
65#include <boost/config/abi_prefix.hpp>
66
67namespace boost
68{
69 namespace detail
70 {
71 namespace win32
72 {
92f5a8d4 73 namespace detail { typedef ticks_type (BOOST_WINAPI_WINAPI_CC *gettickcount64_t)(); }
11fdf7f2 74 extern BOOST_THREAD_DECL boost::detail::win32::detail::gettickcount64_t gettickcount64;
7c673cae
FG
75
76 enum event_type
77 {
78 auto_reset_event=false,
79 manual_reset_event=true
80 };
81
82 enum initial_event_state
83 {
84 event_initially_reset=false,
85 event_initially_set=true
86 };
87
88 inline handle create_event(
89#if !defined(BOOST_NO_ANSI_APIS)
90 const char *mutex_name,
91#else
92 const wchar_t *mutex_name,
93#endif
94 event_type type,
95 initial_event_state state)
96 {
97#if !defined(BOOST_NO_ANSI_APIS)
11fdf7f2 98 handle const res = ::boost::winapi::CreateEventA(0, type, state, mutex_name);
7c673cae 99#elif BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
11fdf7f2 100 handle const res = ::boost::winapi::CreateEventW(0, type, state, mutex_name);
7c673cae 101#else
11fdf7f2 102 handle const res = ::boost::winapi::CreateEventExW(
7c673cae
FG
103 0,
104 mutex_name,
92f5a8d4 105 (type ? create_event_manual_reset : 0) | (state ? create_event_initial_set : 0),
7c673cae
FG
106 event_all_access);
107#endif
108 return res;
109 }
110
111 inline handle create_anonymous_event(event_type type,initial_event_state state)
112 {
113 handle const res = create_event(0, type, state);
114 if(!res)
115 {
116 boost::throw_exception(thread_resource_error());
117 }
118 return res;
119 }
120
121 inline handle create_anonymous_semaphore_nothrow(long initial_count,long max_count)
122 {
123#if !defined(BOOST_NO_ANSI_APIS)
11fdf7f2 124 handle const res=::boost::winapi::CreateSemaphoreA(0,initial_count,max_count,0);
7c673cae
FG
125#else
126#if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
11fdf7f2 127 handle const res=::boost::winapi::CreateSemaphoreEx(0,initial_count,max_count,0,0);
7c673cae 128#else
11fdf7f2 129 handle const res=::boost::winapi::CreateSemaphoreExW(0,initial_count,max_count,0,0,semaphore_all_access);
7c673cae
FG
130#endif
131#endif
132 return res;
133 }
134
135 inline handle create_anonymous_semaphore(long initial_count,long max_count)
136 {
137 handle const res=create_anonymous_semaphore_nothrow(initial_count,max_count);
138 if(!res)
139 {
140 boost::throw_exception(thread_resource_error());
141 }
142 return res;
143 }
144
145 inline handle duplicate_handle(handle source)
146 {
11fdf7f2 147 handle const current_process=::boost::winapi::GetCurrentProcess();
7c673cae
FG
148 long const same_access_flag=2;
149 handle new_handle=0;
11fdf7f2 150 bool const success=::boost::winapi::DuplicateHandle(current_process,source,current_process,&new_handle,0,false,same_access_flag)!=0;
7c673cae
FG
151 if(!success)
152 {
153 boost::throw_exception(thread_resource_error());
154 }
155 return new_handle;
156 }
157
158 inline void release_semaphore(handle semaphore,long count)
159 {
11fdf7f2 160 BOOST_VERIFY(::boost::winapi::ReleaseSemaphore(semaphore,count,0)!=0);
7c673cae
FG
161 }
162
163 inline void get_system_info(system_info *info)
164 {
165#if BOOST_PLAT_WINDOWS_RUNTIME
11fdf7f2 166 ::boost::winapi::GetNativeSystemInfo(info);
7c673cae 167#else
11fdf7f2 168 ::boost::winapi::GetSystemInfo(info);
7c673cae
FG
169#endif
170 }
171
172 inline void sleep(unsigned long milliseconds)
173 {
174 if(milliseconds == 0)
175 {
176#if BOOST_PLAT_WINDOWS_RUNTIME
177 std::this_thread::yield();
178#else
11fdf7f2 179 ::boost::winapi::Sleep(0);
7c673cae
FG
180#endif
181 }
182 else
183 {
184#if BOOST_PLAT_WINDOWS_RUNTIME
11fdf7f2 185 ::boost::winapi::WaitForSingleObjectEx(::boost::winapi::GetCurrentThread(), milliseconds, 0);
7c673cae 186#else
11fdf7f2 187 ::boost::winapi::Sleep(milliseconds);
7c673cae
FG
188#endif
189 }
190 }
191
192#if BOOST_PLAT_WINDOWS_RUNTIME
193 class BOOST_THREAD_DECL scoped_winrt_thread
194 {
195 public:
196 scoped_winrt_thread() : m_completionHandle(invalid_handle_value)
197 {}
198
199 ~scoped_winrt_thread()
200 {
201 if (m_completionHandle != ::boost::detail::win32::invalid_handle_value)
202 {
11fdf7f2 203 ::boost::winapi::CloseHandle(m_completionHandle);
7c673cae
FG
204 }
205 }
206
207 typedef unsigned(__stdcall * thread_func)(void *);
208 bool start(thread_func address, void *parameter, unsigned int *thrdId);
209
210 handle waitable_handle() const
211 {
212 BOOST_ASSERT(m_completionHandle != ::boost::detail::win32::invalid_handle_value);
213 return m_completionHandle;
214 }
215
216 private:
217 handle m_completionHandle;
218 };
219#endif
220 class BOOST_THREAD_DECL handle_manager
221 {
222 private:
223 handle handle_to_manage;
224 handle_manager(handle_manager&);
225 handle_manager& operator=(handle_manager&);
226
227 void cleanup()
228 {
229 if(handle_to_manage && handle_to_manage!=invalid_handle_value)
230 {
11fdf7f2 231 BOOST_VERIFY(::boost::winapi::CloseHandle(handle_to_manage));
7c673cae
FG
232 }
233 }
234
235 public:
236 explicit handle_manager(handle handle_to_manage_):
237 handle_to_manage(handle_to_manage_)
238 {}
239 handle_manager():
240 handle_to_manage(0)
241 {}
242
243 handle_manager& operator=(handle new_handle)
244 {
245 cleanup();
246 handle_to_manage=new_handle;
247 return *this;
248 }
249
250 operator handle() const
251 {
252 return handle_to_manage;
253 }
254
255 handle duplicate() const
256 {
257 return duplicate_handle(handle_to_manage);
258 }
259
260 void swap(handle_manager& other)
261 {
262 std::swap(handle_to_manage,other.handle_to_manage);
263 }
264
265 handle release()
266 {
267 handle const res=handle_to_manage;
268 handle_to_manage=0;
269 return res;
270 }
271
272 bool operator!() const
273 {
274 return !handle_to_manage;
275 }
276
277 ~handle_manager()
278 {
279 cleanup();
280 }
281 };
282 }
283 }
284}
285
286#if defined(BOOST_MSVC) && (_MSC_VER>=1400) && !defined(UNDER_CE)
287
288namespace boost
289{
290 namespace detail
291 {
292 namespace win32
293 {
294#if _MSC_VER==1400
295 extern "C" unsigned char _interlockedbittestandset(long *a,long b);
296 extern "C" unsigned char _interlockedbittestandreset(long *a,long b);
297#else
298 extern "C" unsigned char _interlockedbittestandset(volatile long *a,long b);
299 extern "C" unsigned char _interlockedbittestandreset(volatile long *a,long b);
300#endif
301
302#pragma intrinsic(_interlockedbittestandset)
303#pragma intrinsic(_interlockedbittestandreset)
304
305 inline bool interlocked_bit_test_and_set(long* x,long bit)
306 {
307 return _interlockedbittestandset(x,bit)!=0;
308 }
309
310 inline bool interlocked_bit_test_and_reset(long* x,long bit)
311 {
312 return _interlockedbittestandreset(x,bit)!=0;
313 }
314
315 }
316 }
317}
318#define BOOST_THREAD_BTS_DEFINED
319#elif (defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)) && defined(_M_IX86)
320namespace boost
321{
322 namespace detail
323 {
324 namespace win32
325 {
326 inline bool interlocked_bit_test_and_set(long* x,long bit)
327 {
328#ifndef BOOST_INTEL_CXX_VERSION
329 __asm {
330 mov eax,bit;
331 mov edx,x;
332 lock bts [edx],eax;
333 setc al;
334 };
335#else
336 bool ret;
337 __asm {
338 mov eax,bit
339 mov edx,x
340 lock bts [edx],eax
341 setc al
342 mov ret, al
343 };
344 return ret;
345
346#endif
347 }
348
349 inline bool interlocked_bit_test_and_reset(long* x,long bit)
350 {
351#ifndef BOOST_INTEL_CXX_VERSION
352 __asm {
353 mov eax,bit;
354 mov edx,x;
355 lock btr [edx],eax;
356 setc al;
357 };
358#else
359 bool ret;
360 __asm {
361 mov eax,bit
362 mov edx,x
363 lock btr [edx],eax
364 setc al
365 mov ret, al
366 };
367 return ret;
368
369#endif
370 }
371
372 }
373 }
374}
375#define BOOST_THREAD_BTS_DEFINED
376#endif
377
378#ifndef BOOST_THREAD_BTS_DEFINED
379
380namespace boost
381{
382 namespace detail
383 {
384 namespace win32
385 {
386 inline bool interlocked_bit_test_and_set(long* x,long bit)
387 {
388 long const value=1<<bit;
389 long old=*x;
390 do
391 {
392 long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,old|value,old);
393 if(current==old)
394 {
395 break;
396 }
397 old=current;
398 }
399 while(true) ;
400 return (old&value)!=0;
401 }
402
403 inline bool interlocked_bit_test_and_reset(long* x,long bit)
404 {
405 long const value=1<<bit;
406 long old=*x;
407 do
408 {
409 long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,old&~value,old);
410 if(current==old)
411 {
412 break;
413 }
414 old=current;
415 }
416 while(true) ;
417 return (old&value)!=0;
418 }
419 }
420 }
421}
422#endif
423
424#include <boost/config/abi_suffix.hpp>
425
426#endif