Publishing R3
[platform/upstream/dldt.git] / inference-engine / thirdparty / clDNN / common / boost / 1.64.0 / include / boost-1_64 / boost / thread / win32 / thread_primitives.hpp
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>
19 #include <boost/detail/winapi/config.hpp>
20 //#include <boost/detail/winapi/synchronization.hpp>
21 #include <boost/thread/win32/interlocked_read.hpp>
22 #include <algorithm>
23
24 #if BOOST_PLAT_WINDOWS_RUNTIME
25 #include <thread>
26 #endif
27
28 #if defined( BOOST_USE_WINDOWS_H )
29 # include <windows.h>
30
31 namespace boost
32 {
33     namespace detail
34     {
35         namespace win32
36         {
37             typedef HANDLE handle;
38             typedef SYSTEM_INFO system_info;
39             typedef unsigned __int64 ticks_type;
40             typedef FARPROC farproc_t;
41             unsigned const infinite=INFINITE;
42             unsigned const timeout=WAIT_TIMEOUT;
43             handle const invalid_handle_value=INVALID_HANDLE_VALUE;
44             unsigned const event_modify_state=EVENT_MODIFY_STATE;
45             unsigned const synchronize=SYNCHRONIZE;
46             unsigned const wait_abandoned=WAIT_ABANDONED;
47             unsigned const create_event_initial_set = 0x00000002;
48             unsigned const create_event_manual_reset = 0x00000001;
49             unsigned const event_all_access = EVENT_ALL_ACCESS;
50             unsigned const semaphore_all_access = SEMAPHORE_ALL_ACCESS;
51
52
53 # ifdef BOOST_NO_ANSI_APIS
54 # if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
55             using ::CreateMutexW;
56             using ::CreateEventW;
57             using ::CreateSemaphoreW;
58 # else
59             using ::CreateMutexExW;
60             using ::CreateEventExW;
61             using ::CreateSemaphoreExW;
62 # endif
63             using ::OpenEventW;
64             using ::GetModuleHandleW;
65 # else
66             using ::CreateMutexA;
67             using ::CreateEventA;
68             using ::OpenEventA;
69             using ::CreateSemaphoreA;
70             using ::GetModuleHandleA;
71 # endif
72 #if BOOST_PLAT_WINDOWS_RUNTIME
73             using ::GetNativeSystemInfo;
74             using ::GetTickCount64;
75 #else
76             using ::GetSystemInfo;
77             using ::GetTickCount;
78 #endif
79             using ::CloseHandle;
80             using ::ReleaseMutex;
81             using ::ReleaseSemaphore;
82             using ::SetEvent;
83             using ::ResetEvent;
84             using ::WaitForMultipleObjectsEx;
85             using ::WaitForSingleObjectEx;
86             using ::GetCurrentProcessId;
87             using ::GetCurrentThreadId;
88             using ::GetCurrentThread;
89             using ::GetCurrentProcess;
90             using ::DuplicateHandle;
91 #if !BOOST_PLAT_WINDOWS_RUNTIME
92             using ::SleepEx;
93             using ::Sleep;
94             using ::QueueUserAPC;
95             using ::GetProcAddress;
96 #endif
97         }
98     }
99 }
100 #elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
101
102 # ifdef UNDER_CE
103 #  ifndef WINAPI
104 #   ifndef _WIN32_WCE_EMULATION
105 #    define WINAPI  __cdecl     // Note this doesn't match the desktop definition
106 #   else
107 #    define WINAPI  __stdcall
108 #   endif
109 #  endif
110
111 #  ifdef __cplusplus
112 extern "C" {
113 #  endif
114 typedef int BOOL;
115 typedef unsigned long DWORD;
116 typedef void* HANDLE;
117 #  include <kfuncs.h>
118 #  ifdef __cplusplus
119 }
120 #  endif
121 # endif
122
123 # ifdef __cplusplus
124 extern "C" {
125 # endif
126 struct _SYSTEM_INFO;
127 # ifdef __cplusplus
128 }
129 #endif
130
131 namespace boost
132 {
133     namespace detail
134     {
135         namespace win32
136         {
137 # ifdef _WIN64
138             typedef unsigned __int64 ulong_ptr;
139 # else
140             typedef unsigned long ulong_ptr;
141 # endif
142             typedef void* handle;
143             typedef _SYSTEM_INFO system_info;
144             typedef unsigned __int64 ticks_type;
145             typedef int (__stdcall *farproc_t)();
146             unsigned const infinite=~0U;
147             unsigned const timeout=258U;
148             handle const invalid_handle_value=(handle)(-1);
149             unsigned const event_modify_state=2;
150             unsigned const synchronize=0x100000u;
151             unsigned const wait_abandoned=0x00000080u;
152             unsigned const create_event_initial_set = 0x00000002;
153             unsigned const create_event_manual_reset = 0x00000001;
154             unsigned const event_all_access = 0x1F0003;
155             unsigned const semaphore_all_access = 0x1F0003;
156
157             extern "C"
158             {
159                 struct _SECURITY_ATTRIBUTES;
160 # ifdef BOOST_NO_ANSI_APIS
161 # if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
162                 __declspec(dllimport) void* __stdcall CreateMutexW(_SECURITY_ATTRIBUTES*,int,wchar_t const*);
163                 __declspec(dllimport) void* __stdcall CreateSemaphoreW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*);
164                 __declspec(dllimport) void* __stdcall CreateEventW(_SECURITY_ATTRIBUTES*,int,int,wchar_t const*);
165 # else
166                 __declspec(dllimport) void* __stdcall CreateMutexExW(_SECURITY_ATTRIBUTES*,wchar_t const*,unsigned long,unsigned long);
167                 __declspec(dllimport) void* __stdcall CreateEventExW(_SECURITY_ATTRIBUTES*,wchar_t const*,unsigned long,unsigned long);
168                 __declspec(dllimport) void* __stdcall CreateSemaphoreExW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*,unsigned long,unsigned long);
169 # endif
170                 __declspec(dllimport) void* __stdcall OpenEventW(unsigned long,int,wchar_t const*);
171                 __declspec(dllimport) void* __stdcall GetModuleHandleW(wchar_t const*);
172 # else
173                 __declspec(dllimport) void* __stdcall CreateMutexA(_SECURITY_ATTRIBUTES*,int,char const*);
174                 __declspec(dllimport) void* __stdcall CreateSemaphoreA(_SECURITY_ATTRIBUTES*,long,long,char const*);
175                 __declspec(dllimport) void* __stdcall CreateEventA(_SECURITY_ATTRIBUTES*,int,int,char const*);
176                 __declspec(dllimport) void* __stdcall OpenEventA(unsigned long,int,char const*);
177                 __declspec(dllimport) void* __stdcall GetModuleHandleA(char const*);
178 # endif
179 #if BOOST_PLAT_WINDOWS_RUNTIME
180                 __declspec(dllimport) void __stdcall GetNativeSystemInfo(_SYSTEM_INFO*);
181                 __declspec(dllimport) ticks_type __stdcall GetTickCount64();
182 #else
183                 __declspec(dllimport) void __stdcall GetSystemInfo(_SYSTEM_INFO*);
184                 __declspec(dllimport) unsigned long __stdcall GetTickCount();
185 #endif
186                 __declspec(dllimport) int __stdcall CloseHandle(void*);
187                 __declspec(dllimport) int __stdcall ReleaseMutex(void*);
188                 __declspec(dllimport) unsigned long __stdcall WaitForSingleObjectEx(void*,unsigned long,int);
189                 __declspec(dllimport) unsigned long __stdcall WaitForMultipleObjectsEx(unsigned long nCount,void* const * lpHandles,int bWaitAll,unsigned long dwMilliseconds,int bAlertable);
190                 __declspec(dllimport) int __stdcall ReleaseSemaphore(void*,long,long*);
191                 __declspec(dllimport) int __stdcall DuplicateHandle(void*,void*,void*,void**,unsigned long,int,unsigned long);
192 #if !BOOST_PLAT_WINDOWS_RUNTIME
193                 __declspec(dllimport) unsigned long __stdcall SleepEx(unsigned long,int);
194                 __declspec(dllimport) void __stdcall Sleep(unsigned long);
195                 typedef void (__stdcall *queue_user_apc_callback_function)(ulong_ptr);
196                 __declspec(dllimport) unsigned long __stdcall QueueUserAPC(queue_user_apc_callback_function,void*,ulong_ptr);
197                 __declspec(dllimport) farproc_t __stdcall GetProcAddress(void *, const char *);
198 #endif
199
200 # ifndef UNDER_CE
201                 __declspec(dllimport) unsigned long __stdcall GetCurrentProcessId();
202                 __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId();
203                 __declspec(dllimport) void* __stdcall GetCurrentThread();
204                 __declspec(dllimport) void* __stdcall GetCurrentProcess();
205                 __declspec(dllimport) int __stdcall SetEvent(void*);
206                 __declspec(dllimport) int __stdcall ResetEvent(void*);
207 # else
208                 using ::GetCurrentProcessId;
209                 using ::GetCurrentThreadId;
210                 using ::GetCurrentThread;
211                 using ::GetCurrentProcess;
212                 using ::SetEvent;
213                 using ::ResetEvent;
214 # endif
215             }
216         }
217     }
218 }
219 #else
220 # error "Win32 functions not available"
221 #endif
222
223 #include <boost/config/abi_prefix.hpp>
224
225 namespace boost
226 {
227     namespace detail
228     {
229         namespace win32
230         {
231             namespace detail { typedef ticks_type (__stdcall *gettickcount64_t)(); }
232 #if !BOOST_PLAT_WINDOWS_RUNTIME
233             extern "C"
234             {
235 #ifdef _MSC_VER
236                 long _InterlockedCompareExchange(long volatile *, long, long);
237 #pragma intrinsic(_InterlockedCompareExchange)
238 #elif defined(__MINGW64_VERSION_MAJOR)
239                 long _InterlockedCompareExchange(long volatile *, long, long);
240 #else
241                 // Mingw doesn't provide intrinsics
242 #define _InterlockedCompareExchange InterlockedCompareExchange
243 #endif
244             }
245             // Borrowed from https://stackoverflow.com/questions/8211820/userland-interrupt-timer-access-such-as-via-kequeryinterrupttime-or-similar
246             inline ticks_type __stdcall GetTickCount64emulation()
247             {
248                 static long count = -1l;
249                 unsigned long previous_count, current_tick32, previous_count_zone, current_tick32_zone;
250                 ticks_type current_tick64;
251
252                 previous_count = (unsigned long) boost::detail::interlocked_read_acquire(&count);
253                 current_tick32 = GetTickCount();
254
255                 if(previous_count == (unsigned long)-1l)
256                 {
257                     // count has never been written
258                     unsigned long initial_count;
259                     initial_count = current_tick32 >> 28;
260                     previous_count = (unsigned long) _InterlockedCompareExchange(&count, (long)initial_count, -1l);
261
262                     current_tick64 = initial_count;
263                     current_tick64 <<= 28;
264                     current_tick64 += current_tick32 & 0x0FFFFFFF;
265                     return current_tick64;
266                 }
267
268                 previous_count_zone = previous_count & 15;
269                 current_tick32_zone = current_tick32 >> 28;
270
271                 if(current_tick32_zone == previous_count_zone)
272                 {
273                     // The top four bits of the 32-bit tick count haven't changed since count was last written.
274                     current_tick64 = previous_count;
275                     current_tick64 <<= 28;
276                     current_tick64 += current_tick32 & 0x0FFFFFFF;
277                     return current_tick64;
278                 }
279
280                 if(current_tick32_zone == previous_count_zone + 1 || (current_tick32_zone == 0 && previous_count_zone == 15))
281                 {
282                     // The top four bits of the 32-bit tick count have been incremented since count was last written.
283                     unsigned long new_count = previous_count + 1;
284                     _InterlockedCompareExchange(&count, (long)new_count, (long)previous_count);
285                     current_tick64 = new_count;
286                     current_tick64 <<= 28;
287                     current_tick64 += current_tick32 & 0x0FFFFFFF;
288                     return current_tick64;
289                 }
290
291                 // Oops, we weren't called often enough, we're stuck
292                 return 0xFFFFFFFF;
293             }
294 #else
295 #endif
296             inline detail::gettickcount64_t GetTickCount64_()
297             {
298                 static detail::gettickcount64_t gettickcount64impl;
299                 if(gettickcount64impl)
300                     return gettickcount64impl;
301
302                 // GetTickCount and GetModuleHandle are not allowed in the Windows Runtime,
303                 // and kernel32 isn't used in Windows Phone.
304 #if BOOST_PLAT_WINDOWS_RUNTIME
305                 gettickcount64impl = &GetTickCount64;
306 #else
307                 farproc_t addr=GetProcAddress(
308 #if !defined(BOOST_NO_ANSI_APIS)
309                     GetModuleHandleA("KERNEL32.DLL"),
310 #else
311                     GetModuleHandleW(L"KERNEL32.DLL"),
312 #endif
313                     "GetTickCount64");
314                 if(addr)
315                     gettickcount64impl=(detail::gettickcount64_t) addr;
316                 else
317                     gettickcount64impl=&GetTickCount64emulation;
318 #endif
319                 return gettickcount64impl;
320             }
321
322             enum event_type
323             {
324                 auto_reset_event=false,
325                 manual_reset_event=true
326             };
327
328             enum initial_event_state
329             {
330                 event_initially_reset=false,
331                 event_initially_set=true
332             };
333
334             inline handle create_event(
335 #if !defined(BOOST_NO_ANSI_APIS)
336                 const char *mutex_name,
337 #else
338                 const wchar_t *mutex_name,
339 #endif
340                 event_type type,
341                 initial_event_state state)
342             {
343 #if !defined(BOOST_NO_ANSI_APIS)
344                 handle const res = win32::CreateEventA(0, type, state, mutex_name);
345 #elif BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
346                 handle const res = win32::CreateEventW(0, type, state, mutex_name);
347 #else
348                 handle const res = win32::CreateEventExW(
349                     0,
350                     mutex_name,
351                     type ? create_event_manual_reset : 0 | state ? create_event_initial_set : 0,
352                     event_all_access);
353 #endif
354                 return res;
355             }
356
357             inline handle create_anonymous_event(event_type type,initial_event_state state)
358             {
359                 handle const res = create_event(0, type, state);
360                 if(!res)
361                 {
362                     boost::throw_exception(thread_resource_error());
363                 }
364                 return res;
365             }
366
367             inline handle create_anonymous_semaphore_nothrow(long initial_count,long max_count)
368             {
369 #if !defined(BOOST_NO_ANSI_APIS)
370                 handle const res=win32::CreateSemaphoreA(0,initial_count,max_count,0);
371 #else
372 #if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
373                 handle const res=win32::CreateSemaphoreEx(0,initial_count,max_count,0,0);
374 #else
375                 handle const res=win32::CreateSemaphoreExW(0,initial_count,max_count,0,0,semaphore_all_access);
376 #endif
377 #endif
378                 return res;
379             }
380
381             inline handle create_anonymous_semaphore(long initial_count,long max_count)
382             {
383                 handle const res=create_anonymous_semaphore_nothrow(initial_count,max_count);
384                 if(!res)
385                 {
386                     boost::throw_exception(thread_resource_error());
387                 }
388                 return res;
389             }
390
391             inline handle duplicate_handle(handle source)
392             {
393                 handle const current_process=GetCurrentProcess();
394                 long const same_access_flag=2;
395                 handle new_handle=0;
396                 bool const success=DuplicateHandle(current_process,source,current_process,&new_handle,0,false,same_access_flag)!=0;
397                 if(!success)
398                 {
399                     boost::throw_exception(thread_resource_error());
400                 }
401                 return new_handle;
402             }
403
404             inline void release_semaphore(handle semaphore,long count)
405             {
406                 BOOST_VERIFY(ReleaseSemaphore(semaphore,count,0)!=0);
407             }
408
409             inline void get_system_info(system_info *info)
410             {
411 #if BOOST_PLAT_WINDOWS_RUNTIME
412                 win32::GetNativeSystemInfo(info);
413 #else
414                 win32::GetSystemInfo(info);
415 #endif
416             }
417
418             inline void sleep(unsigned long milliseconds)
419             {
420                 if(milliseconds == 0)
421                 {
422 #if BOOST_PLAT_WINDOWS_RUNTIME
423                     std::this_thread::yield();
424 #else
425                     ::boost::detail::win32::Sleep(0);
426 #endif
427                 }
428                 else
429                 {
430 #if BOOST_PLAT_WINDOWS_RUNTIME
431                     ::boost::detail::win32::WaitForSingleObjectEx(::boost::detail::win32::GetCurrentThread(), milliseconds, 0);
432 #else
433                     ::boost::detail::win32::Sleep(milliseconds);
434 #endif
435                 }
436             }
437
438 #if BOOST_PLAT_WINDOWS_RUNTIME
439             class BOOST_THREAD_DECL scoped_winrt_thread
440             {
441             public:
442                 scoped_winrt_thread() : m_completionHandle(invalid_handle_value)
443                 {}
444
445                 ~scoped_winrt_thread()
446                 {
447                     if (m_completionHandle != ::boost::detail::win32::invalid_handle_value)
448                     {
449                         CloseHandle(m_completionHandle);
450                     }
451                 }
452
453                 typedef unsigned(__stdcall * thread_func)(void *);
454                 bool start(thread_func address, void *parameter, unsigned int *thrdId);
455
456                 handle waitable_handle() const
457                 {
458                     BOOST_ASSERT(m_completionHandle != ::boost::detail::win32::invalid_handle_value);
459                     return m_completionHandle;
460                 }
461
462             private:
463                 handle m_completionHandle;
464             };
465 #endif
466             class BOOST_THREAD_DECL handle_manager
467             {
468             private:
469                 handle handle_to_manage;
470                 handle_manager(handle_manager&);
471                 handle_manager& operator=(handle_manager&);
472
473                 void cleanup()
474                 {
475                     if(handle_to_manage && handle_to_manage!=invalid_handle_value)
476                     {
477                         BOOST_VERIFY(CloseHandle(handle_to_manage));
478                     }
479                 }
480
481             public:
482                 explicit handle_manager(handle handle_to_manage_):
483                     handle_to_manage(handle_to_manage_)
484                 {}
485                 handle_manager():
486                     handle_to_manage(0)
487                 {}
488
489                 handle_manager& operator=(handle new_handle)
490                 {
491                     cleanup();
492                     handle_to_manage=new_handle;
493                     return *this;
494                 }
495
496                 operator handle() const
497                 {
498                     return handle_to_manage;
499                 }
500
501                 handle duplicate() const
502                 {
503                     return duplicate_handle(handle_to_manage);
504                 }
505
506                 void swap(handle_manager& other)
507                 {
508                     std::swap(handle_to_manage,other.handle_to_manage);
509                 }
510
511                 handle release()
512                 {
513                     handle const res=handle_to_manage;
514                     handle_to_manage=0;
515                     return res;
516                 }
517
518                 bool operator!() const
519                 {
520                     return !handle_to_manage;
521                 }
522
523                 ~handle_manager()
524                 {
525                     cleanup();
526                 }
527             };
528         }
529     }
530 }
531
532 #if defined(BOOST_MSVC) && (_MSC_VER>=1400)  && !defined(UNDER_CE)
533
534 namespace boost
535 {
536     namespace detail
537     {
538         namespace win32
539         {
540 #if _MSC_VER==1400
541             extern "C" unsigned char _interlockedbittestandset(long *a,long b);
542             extern "C" unsigned char _interlockedbittestandreset(long *a,long b);
543 #else
544             extern "C" unsigned char _interlockedbittestandset(volatile long *a,long b);
545             extern "C" unsigned char _interlockedbittestandreset(volatile long *a,long b);
546 #endif
547
548 #pragma intrinsic(_interlockedbittestandset)
549 #pragma intrinsic(_interlockedbittestandreset)
550
551             inline bool interlocked_bit_test_and_set(long* x,long bit)
552             {
553                 return _interlockedbittestandset(x,bit)!=0;
554             }
555
556             inline bool interlocked_bit_test_and_reset(long* x,long bit)
557             {
558                 return _interlockedbittestandreset(x,bit)!=0;
559             }
560
561         }
562     }
563 }
564 #define BOOST_THREAD_BTS_DEFINED
565 #elif (defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)) && defined(_M_IX86)
566 namespace boost
567 {
568     namespace detail
569     {
570         namespace win32
571         {
572             inline bool interlocked_bit_test_and_set(long* x,long bit)
573             {
574 #ifndef BOOST_INTEL_CXX_VERSION
575                 __asm {
576                     mov eax,bit;
577                     mov edx,x;
578                     lock bts [edx],eax;
579                     setc al;
580                 };
581 #else
582                 bool ret;
583                 __asm {
584                     mov eax,bit
585                     mov edx,x
586                     lock bts [edx],eax
587                     setc al
588                     mov ret, al
589                 };
590                 return ret;
591
592 #endif
593             }
594
595             inline bool interlocked_bit_test_and_reset(long* x,long bit)
596             {
597 #ifndef BOOST_INTEL_CXX_VERSION
598                 __asm {
599                     mov eax,bit;
600                     mov edx,x;
601                     lock btr [edx],eax;
602                     setc al;
603                 };
604 #else
605                 bool ret;
606                 __asm {
607                     mov eax,bit
608                     mov edx,x
609                     lock btr [edx],eax
610                     setc al
611                     mov ret, al
612                 };
613                 return ret;
614
615 #endif
616             }
617
618         }
619     }
620 }
621 #define BOOST_THREAD_BTS_DEFINED
622 #endif
623
624 #ifndef BOOST_THREAD_BTS_DEFINED
625
626 namespace boost
627 {
628     namespace detail
629     {
630         namespace win32
631         {
632             inline bool interlocked_bit_test_and_set(long* x,long bit)
633             {
634                 long const value=1<<bit;
635                 long old=*x;
636                 do
637                 {
638                     long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,old|value,old);
639                     if(current==old)
640                     {
641                         break;
642                     }
643                     old=current;
644                 }
645                 while(true) ;
646                 return (old&value)!=0;
647             }
648
649             inline bool interlocked_bit_test_and_reset(long* x,long bit)
650             {
651                 long const value=1<<bit;
652                 long old=*x;
653                 do
654                 {
655                     long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,old&~value,old);
656                     if(current==old)
657                     {
658                         break;
659                     }
660                     old=current;
661                 }
662                 while(true) ;
663                 return (old&value)!=0;
664             }
665         }
666     }
667 }
668 #endif
669
670 #include <boost/config/abi_suffix.hpp>
671
672 #endif