aboutsummaryrefslogtreecommitdiff
path: root/src/threading.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/threading.h')
-rw-r--r--src/threading.h208
1 files changed, 56 insertions, 152 deletions
diff --git a/src/threading.h b/src/threading.h
index 82c8f52..c443c82 100644
--- a/src/threading.h
+++ b/src/threading.h
@@ -16,22 +16,24 @@
16#define THREADAPI THREADAPI_PTHREAD 16#define THREADAPI THREADAPI_PTHREAD
17#endif // (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) 17#endif // (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC)
18 18
19/*---=== Locks & Signals ===--- 19static constexpr int THREAD_PRIO_DEFAULT{ -999 };
20*/
21 20
21// ##################################################################################################
22// ##################################################################################################
22#if THREADAPI == THREADAPI_WINDOWS 23#if THREADAPI == THREADAPI_WINDOWS
23 #if defined( PLATFORM_XBOX) 24
24 #include <xtl.h> 25#if defined(PLATFORM_XBOX)
25 #else // !PLATFORM_XBOX 26#include <xtl.h>
26 #define WIN32_LEAN_AND_MEAN 27#else // !PLATFORM_XBOX
27 // CONDITION_VARIABLE needs version 0x0600+ 28#define WIN32_LEAN_AND_MEAN
28 // _WIN32_WINNT value is already defined by MinGW, but not by MSVC 29// CONDITION_VARIABLE needs version 0x0600+
29 #ifndef _WIN32_WINNT 30// _WIN32_WINNT value is already defined by MinGW, but not by MSVC
30 #define _WIN32_WINNT 0x0600 31#ifndef _WIN32_WINNT
31 #endif // _WIN32_WINNT 32#define _WIN32_WINNT 0x0600
32 #include <windows.h> 33#endif // _WIN32_WINNT
33 #endif // !PLATFORM_XBOX 34#include <windows.h>
34 #include <process.h> 35#endif // !PLATFORM_XBOX
36#include <process.h>
35 37
36/* 38/*
37#define XSTR(x) STR(x) 39#define XSTR(x) STR(x)
@@ -39,148 +41,50 @@
39#pragma message( "The value of _WIN32_WINNT: " XSTR(_WIN32_WINNT)) 41#pragma message( "The value of _WIN32_WINNT: " XSTR(_WIN32_WINNT))
40*/ 42*/
41 43
42 // MSDN: http://msdn2.microsoft.com/en-us/library/ms684254.aspx 44static constexpr int THREAD_PRIO_MIN{ -3 };
43 // 45static constexpr int THREAD_PRIO_MAX{ +3 };
44 // CRITICAL_SECTION can be used for simple code protection. Mutexes are
45 // needed for use with the SIGNAL system.
46 //
47
48 #if _WIN32_WINNT < 0x0600 // CONDITION_VARIABLE aren't available, use a signal
49
50 struct SIGNAL_T
51 {
52 CRITICAL_SECTION signalCS;
53 CRITICAL_SECTION countCS;
54 HANDLE waitEvent;
55 HANDLE waitDoneEvent;
56 LONG waitersCount;
57 };
58
59
60 #else // CONDITION_VARIABLE are available, use them
61 46
62 #define SIGNAL_T CONDITION_VARIABLE 47// ##################################################################################################
63 #define MUTEX_INIT( ref) InitializeCriticalSection( ref) 48// ##################################################################################################
64 #define MUTEX_FREE( ref) DeleteCriticalSection( ref)
65 #define MUTEX_LOCK( ref) EnterCriticalSection( ref)
66 #define MUTEX_UNLOCK( ref) LeaveCriticalSection( ref)
67
68 #endif // CONDITION_VARIABLE are available
69
70 #define MUTEX_RECURSIVE_INIT(ref) MUTEX_INIT(ref) /* always recursive in Win32 */
71
72 using THREAD_RETURN_T = unsigned int;
73
74 #define YIELD() Sleep(0)
75 #define THREAD_CALLCONV __stdcall
76#else // THREADAPI == THREADAPI_PTHREAD 49#else // THREADAPI == THREADAPI_PTHREAD
77 // PThread (Linux, OS X, ...) 50// ##################################################################################################
78 51// ##################################################################################################
79 // looks like some MinGW installations don't support PTW32_INCLUDE_WINDOWS_H, so let's include it ourselves, just in case 52
80 #if defined(PLATFORM_WIN32) 53// PThread (Linux, OS X, ...)
81 #include <windows.h> 54
82 #endif // PLATFORM_WIN32 55// looks like some MinGW installations don't support PTW32_INCLUDE_WINDOWS_H, so let's include it ourselves, just in case
83 #include <pthread.h> 56#if defined(PLATFORM_WIN32)
84 57#include <windows.h>
85 #ifdef PLATFORM_LINUX 58#endif // PLATFORM_WIN32
86 #if defined(__GLIBC__) 59#include <pthread.h>
87 # define _MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP 60
88 #else 61// Yield is non-portable:
89 # define _MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE 62//
90 #endif 63// OS X 10.4.8/9 has pthread_yield_np()
91 #else 64// Linux 2.4 has pthread_yield() if _GNU_SOURCE is #defined
92 /* OS X, ... */ 65// FreeBSD 6.2 has pthread_yield()
93 # define _MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE 66// ...
94 #endif 67//
95 68
96 #define MUTEX_INIT(ref) pthread_mutex_init(ref, nullptr) 69#if defined(PLATFORM_LINUX)
97 #define MUTEX_RECURSIVE_INIT(ref) \ 70extern volatile bool sudo;
98 { pthread_mutexattr_t a; pthread_mutexattr_init( &a ); \ 71# ifdef LINUX_SCHED_RR
99 pthread_mutexattr_settype( &a, _MUTEX_RECURSIVE ); \ 72# define THREAD_PRIO_MIN (sudo ? -3 : 0)
100 pthread_mutex_init(ref,&a); pthread_mutexattr_destroy( &a ); \ 73# else
101 } 74static constexpr int THREAD_PRIO_MIN{ 0 };
102 #define MUTEX_FREE(ref) pthread_mutex_destroy(ref) 75#endif
103 #define MUTEX_LOCK(ref) pthread_mutex_lock(ref) 76# define THREAD_PRIO_MAX (sudo ? +3 : 0)
104 #define MUTEX_UNLOCK(ref) pthread_mutex_unlock(ref) 77#else
105 78static constexpr int THREAD_PRIO_MIN{ -3 };
106 using THREAD_RETURN_T = void *; 79static constexpr int THREAD_PRIO_MAX{ +3 };
107 80#endif
108 using SIGNAL_T = pthread_cond_t;
109
110 // Yield is non-portable:
111 //
112 // OS X 10.4.8/9 has pthread_yield_np()
113 // Linux 2.4 has pthread_yield() if _GNU_SOURCE is #defined
114 // FreeBSD 6.2 has pthread_yield()
115 // ...
116 //
117 #if defined( PLATFORM_OSX)
118 #define YIELD() pthread_yield_np()
119 #else
120 #define YIELD() sched_yield()
121 #endif
122 #define THREAD_CALLCONV
123#endif //THREADAPI == THREADAPI_PTHREAD
124
125/*---=== Threading ===---
126*/
127
128#define THREAD_PRIO_DEFAULT (-999)
129
130#if THREADAPI == THREADAPI_WINDOWS
131
132# define THREAD_PRIO_MIN (-3)
133# define THREAD_PRIO_MAX (+3)
134
135#else // THREADAPI == THREADAPI_PTHREAD
136
137 /* Platforms that have a timed 'pthread_join()' can get away with a simpler
138 * implementation. Others will use a condition variable.
139 */
140# if defined __WINPTHREADS_VERSION
141//# define USE_PTHREAD_TIMEDJOIN
142# endif // __WINPTHREADS_VERSION
143
144# ifdef USE_PTHREAD_TIMEDJOIN
145# ifdef PLATFORM_OSX
146# error "No 'pthread_timedjoin()' on this system"
147# else
148 /* Linux, ... */
149# define PTHREAD_TIMEDJOIN pthread_timedjoin_np
150# endif
151# endif
152
153# if defined(PLATFORM_LINUX)
154 extern volatile bool sudo;
155# ifdef LINUX_SCHED_RR
156# define THREAD_PRIO_MIN (sudo ? -3 : 0)
157# else
158# define THREAD_PRIO_MIN (0)
159# endif
160# define THREAD_PRIO_MAX (sudo ? +3 : 0)
161# else
162# define THREAD_PRIO_MIN (-3)
163# define THREAD_PRIO_MAX (+3)
164# endif
165 81
166#endif // THREADAPI == THREADAPI_WINDOWS 82#endif // THREADAPI == THREADAPI_WINDOWS
83// ##################################################################################################
84// ##################################################################################################
167 85
168/* 86void THREAD_SETNAME(char const* _name);
169* Win32 and PTHREAD_TIMEDJOIN allow waiting for a thread with a timeout. 87void THREAD_SET_PRIORITY(int prio);
170* Posix without PTHREAD_TIMEDJOIN needs to use a condition variable approach. 88void THREAD_SET_AFFINITY(unsigned int aff);
171*/
172#define THREADWAIT_TIMEOUT 1
173#define THREADWAIT_CONDVAR 2
174
175#if THREADAPI == THREADAPI_WINDOWS || (defined PTHREAD_TIMEDJOIN)
176#define THREADWAIT_METHOD THREADWAIT_TIMEOUT
177#else // THREADAPI == THREADAPI_WINDOWS || (defined PTHREAD_TIMEDJOIN)
178#define THREADWAIT_METHOD THREADWAIT_CONDVAR
179#endif // THREADAPI == THREADAPI_WINDOWS || (defined PTHREAD_TIMEDJOIN)
180
181
182void THREAD_SETNAME( char const* _name);
183void THREAD_SET_PRIORITY( int prio);
184void THREAD_SET_AFFINITY( unsigned int aff);
185 89
186void JTHREAD_SET_PRIORITY(std::jthread& thread_, int prio_); 90void JTHREAD_SET_PRIORITY(std::jthread& thread_, int prio_);