diff options
Diffstat (limited to '')
-rw-r--r-- | src/threading.cpp | 351 |
1 files changed, 174 insertions, 177 deletions
diff --git a/src/threading.cpp b/src/threading.cpp index acc79d8..254b2e3 100644 --- a/src/threading.cpp +++ b/src/threading.cpp | |||
@@ -6,7 +6,7 @@ | |||
6 | * | 6 | * |
7 | * References: | 7 | * References: |
8 | * <http://www.cse.wustl.edu/~schmidt/win32-cv-1.html> | 8 | * <http://www.cse.wustl.edu/~schmidt/win32-cv-1.html> |
9 | */ | 9 | */ |
10 | 10 | ||
11 | /* | 11 | /* |
12 | =============================================================================== | 12 | =============================================================================== |
@@ -36,35 +36,34 @@ THE SOFTWARE. | |||
36 | */ | 36 | */ |
37 | #if defined(__linux__) | 37 | #if defined(__linux__) |
38 | 38 | ||
39 | # ifndef _GNU_SOURCE // definition by the makefile can cause a redefinition error | 39 | #ifndef _GNU_SOURCE // definition by the makefile can cause a redefinition error |
40 | # define _GNU_SOURCE // must be defined before any include | 40 | #define _GNU_SOURCE // must be defined before any include |
41 | # endif // _GNU_SOURCE | 41 | #endif // _GNU_SOURCE |
42 | 42 | ||
43 | # ifdef __ANDROID__ | 43 | #ifdef __ANDROID__ |
44 | # include <android/log.h> | 44 | #include <android/log.h> |
45 | # define LOG_TAG "LuaLanes" | 45 | #define LOG_TAG "LuaLanes" |
46 | # endif // __ANDROID__ | 46 | #endif // __ANDROID__ |
47 | 47 | ||
48 | #endif // __linux__ | 48 | #endif // __linux__ |
49 | 49 | ||
50 | #include "threading.h" | 50 | #include "threading.h" |
51 | 51 | ||
52 | #if !defined( PLATFORM_XBOX) && !defined( PLATFORM_WIN32) && !defined( PLATFORM_POCKETPC) | 52 | #if !defined(PLATFORM_XBOX) && !defined(PLATFORM_WIN32) && !defined(PLATFORM_POCKETPC) |
53 | # include <sys/time.h> | 53 | #include <sys/time.h> |
54 | #endif // non-WIN32 timing | 54 | #endif // non-WIN32 timing |
55 | 55 | ||
56 | |||
57 | #if defined(PLATFORM_LINUX) || defined(PLATFORM_CYGWIN) | 56 | #if defined(PLATFORM_LINUX) || defined(PLATFORM_CYGWIN) |
58 | # include <sys/types.h> | 57 | #include <sys/types.h> |
59 | # include <unistd.h> | 58 | #include <unistd.h> |
60 | #endif | 59 | #endif |
61 | 60 | ||
62 | #ifdef PLATFORM_OSX | 61 | #ifdef PLATFORM_OSX |
63 | # include "threading_osx.h" | 62 | #include "threading_osx.h" |
64 | #endif | 63 | #endif |
65 | 64 | ||
66 | /* Linux with older glibc (such as Debian) don't have pthread_setname_np, but have prctl | 65 | /* Linux with older glibc (such as Debian) don't have pthread_setname_np, but have prctl |
67 | */ | 66 | */ |
68 | #if defined PLATFORM_LINUX | 67 | #if defined PLATFORM_LINUX |
69 | #if defined __GNU_LIBRARY__ && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 12 | 68 | #if defined __GNU_LIBRARY__ && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 12 |
70 | #define LINUX_USE_PTHREAD_SETNAME_NP 1 | 69 | #define LINUX_USE_PTHREAD_SETNAME_NP 1 |
@@ -76,41 +75,39 @@ THE SOFTWARE. | |||
76 | 75 | ||
77 | #ifdef _MSC_VER | 76 | #ifdef _MSC_VER |
78 | // ".. selected for automatic inline expansion" (/O2 option) | 77 | // ".. selected for automatic inline expansion" (/O2 option) |
79 | # pragma warning( disable : 4711 ) | 78 | #pragma warning(disable : 4711) |
80 | // ".. type cast from function pointer ... to data pointer" | 79 | // ".. type cast from function pointer ... to data pointer" |
81 | # pragma warning( disable : 4054 ) | 80 | #pragma warning(disable : 4054) |
82 | #endif | 81 | #endif |
83 | 82 | ||
84 | /* | 83 | /* |
85 | * FAIL is for unexpected API return values - essentially programming | 84 | * FAIL is for unexpected API return values - essentially programming |
86 | * error in _this_ code. | 85 | * error in _this_ code. |
87 | */ | 86 | */ |
88 | #if defined(PLATFORM_XBOX) || defined(PLATFORM_WIN32) || defined(PLATFORM_POCKETPC) | 87 | #if defined(PLATFORM_XBOX) || defined(PLATFORM_WIN32) || defined(PLATFORM_POCKETPC) |
89 | static void FAIL(char const* funcname, int rc) | 88 | static void FAIL(char const* funcname, int rc) |
90 | { | 89 | { |
91 | #if defined(PLATFORM_XBOX) | 90 | #if defined(PLATFORM_XBOX) |
92 | fprintf(stderr, "%s() failed! (%d)\n", funcname, rc); | 91 | fprintf(stderr, "%s() failed! (%d)\n", funcname, rc); |
93 | #else // PLATFORM_XBOX | 92 | #else // PLATFORM_XBOX |
94 | char buf[256]; | 93 | char buf[256]; |
95 | FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 256, nullptr); | 94 | FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 256, nullptr); |
96 | fprintf(stderr, "%s() failed! [GetLastError() -> %d] '%s'", funcname, rc, buf); | 95 | fprintf(stderr, "%s() failed! [GetLastError() -> %d] '%s'", funcname, rc, buf); |
97 | #endif // PLATFORM_XBOX | 96 | #endif // PLATFORM_XBOX |
98 | #ifdef _MSC_VER | 97 | #ifdef _MSC_VER |
99 | __debugbreak(); // give a chance to the debugger! | 98 | __debugbreak(); // give a chance to the debugger! |
100 | #endif // _MSC_VER | 99 | #endif // _MSC_VER |
101 | abort(); | 100 | abort(); |
102 | } | 101 | } |
103 | #endif // win32 build | 102 | #endif // win32 build |
104 | 103 | ||
105 | |||
106 | /*---=== Threading ===---*/ | 104 | /*---=== Threading ===---*/ |
107 | 105 | ||
108 | // ################################################################################################# | 106 | // ################################################################################################# |
109 | // ################################################################################################# | 107 | // ################################################################################################# |
110 | #if THREADAPI == THREADAPI_WINDOWS | 108 | #if THREADAPI == THREADAPI_WINDOWS |
111 | 109 | ||
112 | static int const gs_prio_remap[] = | 110 | static int const gs_prio_remap[] = { |
113 | { | ||
114 | THREAD_PRIORITY_IDLE, | 111 | THREAD_PRIORITY_IDLE, |
115 | THREAD_PRIORITY_LOWEST, | 112 | THREAD_PRIORITY_LOWEST, |
116 | THREAD_PRIORITY_BELOW_NORMAL, | 113 | THREAD_PRIORITY_BELOW_NORMAL, |
@@ -125,8 +122,7 @@ static int const gs_prio_remap[] = | |||
125 | void THREAD_SET_PRIORITY(int prio_, [[maybe_unused]] bool sudo_) | 122 | void THREAD_SET_PRIORITY(int prio_, [[maybe_unused]] bool sudo_) |
126 | { | 123 | { |
127 | // prio range [-3,+3] was checked by the caller | 124 | // prio range [-3,+3] was checked by the caller |
128 | if (!SetThreadPriority(GetCurrentThread(), gs_prio_remap[prio_ + 3])) | 125 | if (!SetThreadPriority(GetCurrentThread(), gs_prio_remap[prio_ + 3])) { |
129 | { | ||
130 | FAIL("THREAD_SET_PRIORITY", GetLastError()); | 126 | FAIL("THREAD_SET_PRIORITY", GetLastError()); |
131 | } | 127 | } |
132 | } | 128 | } |
@@ -136,8 +132,7 @@ void THREAD_SET_PRIORITY(int prio_, [[maybe_unused]] bool sudo_) | |||
136 | void JTHREAD_SET_PRIORITY(std::jthread& thread_, int prio_, [[maybe_unused]] bool sudo_) | 132 | void JTHREAD_SET_PRIORITY(std::jthread& thread_, int prio_, [[maybe_unused]] bool sudo_) |
137 | { | 133 | { |
138 | // prio range [-3,+3] was checked by the caller | 134 | // prio range [-3,+3] was checked by the caller |
139 | if (!SetThreadPriority(thread_.native_handle(), gs_prio_remap[prio_ + 3])) | 135 | if (!SetThreadPriority(thread_.native_handle(), gs_prio_remap[prio_ + 3])) { |
140 | { | ||
141 | FAIL("JTHREAD_SET_PRIORITY", GetLastError()); | 136 | FAIL("JTHREAD_SET_PRIORITY", GetLastError()); |
142 | } | 137 | } |
143 | } | 138 | } |
@@ -146,8 +141,7 @@ void JTHREAD_SET_PRIORITY(std::jthread& thread_, int prio_, [[maybe_unused]] boo | |||
146 | 141 | ||
147 | void THREAD_SET_AFFINITY(unsigned int aff) | 142 | void THREAD_SET_AFFINITY(unsigned int aff) |
148 | { | 143 | { |
149 | if (!SetThreadAffinityMask(GetCurrentThread(), aff)) | 144 | if (!SetThreadAffinityMask(GetCurrentThread(), aff)) { |
150 | { | ||
151 | FAIL("THREAD_SET_AFFINITY", GetLastError()); | 145 | FAIL("THREAD_SET_AFFINITY", GetLastError()); |
152 | } | 146 | } |
153 | } | 147 | } |
@@ -155,15 +149,15 @@ void THREAD_SET_AFFINITY(unsigned int aff) | |||
155 | // ################################################################################################# | 149 | // ################################################################################################# |
156 | 150 | ||
157 | #if !defined __GNUC__ | 151 | #if !defined __GNUC__ |
158 | //see http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx | 152 | // see http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx |
159 | #define MS_VC_EXCEPTION 0x406D1388 | 153 | #define MS_VC_EXCEPTION 0x406D1388 |
160 | #pragma pack(push,8) | 154 | #pragma pack(push, 8) |
161 | typedef struct tagTHREADNAME_INFO | 155 | typedef struct tagTHREADNAME_INFO |
162 | { | 156 | { |
163 | DWORD dwType; // Must be 0x1000. | 157 | DWORD dwType; // Must be 0x1000. |
164 | LPCSTR szName; // Pointer to name (in user addr space). | 158 | LPCSTR szName; // Pointer to name (in user addr space). |
165 | DWORD dwThreadID; // Thread ID (-1=caller thread). | 159 | DWORD dwThreadID; // Thread ID (-1=caller thread). |
166 | DWORD dwFlags; // Reserved for future use, must be zero. | 160 | DWORD dwFlags; // Reserved for future use, must be zero. |
167 | } THREADNAME_INFO; | 161 | } THREADNAME_INFO; |
168 | #pragma pack(pop) | 162 | #pragma pack(pop) |
169 | #endif // !__GNUC__ | 163 | #endif // !__GNUC__ |
@@ -177,12 +171,9 @@ void THREAD_SETNAME(char const* _name) | |||
177 | info.dwThreadID = GetCurrentThreadId(); | 171 | info.dwThreadID = GetCurrentThreadId(); |
178 | info.dwFlags = 0; | 172 | info.dwFlags = 0; |
179 | 173 | ||
180 | __try | 174 | __try { |
181 | { | 175 | RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*) &info); |
182 | RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info ); | 176 | } __except (EXCEPTION_EXECUTE_HANDLER) { |
183 | } | ||
184 | __except(EXCEPTION_EXECUTE_HANDLER) | ||
185 | { | ||
186 | } | 177 | } |
187 | #endif // !__GNUC__ | 178 | #endif // !__GNUC__ |
188 | } | 179 | } |
@@ -211,8 +202,7 @@ void THREAD_SETNAME(char const* _name) | |||
211 | #undef pthread_attr_setschedpolicy | 202 | #undef pthread_attr_setschedpolicy |
212 | [[nodiscard]] static int pthread_attr_setschedpolicy(pthread_attr_t* attr, int policy) | 203 | [[nodiscard]] static int pthread_attr_setschedpolicy(pthread_attr_t* attr, int policy) |
213 | { | 204 | { |
214 | if (policy != SCHED_OTHER) | 205 | if (policy != SCHED_OTHER) { |
215 | { | ||
216 | return ENOTSUP; | 206 | return ENOTSUP; |
217 | } | 207 | } |
218 | return 0; | 208 | return 0; |
@@ -220,131 +210,140 @@ void THREAD_SETNAME(char const* _name) | |||
220 | #endif // pthread_attr_setschedpolicy() | 210 | #endif // pthread_attr_setschedpolicy() |
221 | #endif // defined(__MINGW32__) || defined(__MINGW64__) | 211 | #endif // defined(__MINGW32__) || defined(__MINGW64__) |
222 | 212 | ||
223 | static void _PT_FAIL( int rc, const char *name, const char *file, int line ) | 213 | static void _PT_FAIL(int rc, const char* name, const char* file, int line) |
224 | { | 214 | { |
225 | const char *why= (rc==EINVAL) ? "EINVAL" : | 215 | const char* why = (rc == EINVAL) ? "EINVAL" |
226 | (rc==EBUSY) ? "EBUSY" : | 216 | : (rc == EBUSY) ? "EBUSY" |
227 | (rc==EPERM) ? "EPERM" : | 217 | : (rc == EPERM) ? "EPERM" |
228 | (rc==ENOMEM) ? "ENOMEM" : | 218 | : (rc == ENOMEM) ? "ENOMEM" |
229 | (rc==ESRCH) ? "ESRCH" : | 219 | : (rc == ESRCH) ? "ESRCH" |
230 | (rc==ENOTSUP) ? "ENOTSUP": | 220 | : (rc == ENOTSUP) ? "ENOTSUP" |
231 | //... | 221 | : "<UNKNOWN>"; |
232 | "<UNKNOWN>"; | 222 | fprintf(stderr, "%s %d: %s failed, %d %s\n", file, line, name, rc, why); |
233 | fprintf( stderr, "%s %d: %s failed, %d %s\n", file, line, name, rc, why ); | ||
234 | abort(); | 223 | abort(); |
235 | } | 224 | } |
236 | #define PT_CALL( call ) { int rc= call; if (rc!=0) _PT_FAIL( rc, #call, __FILE__, __LINE__ ); } | 225 | #define PT_CALL(call) \ |
226 | { \ | ||
227 | int rc = call; \ | ||
228 | if (rc != 0) \ | ||
229 | _PT_FAIL(rc, #call, __FILE__, __LINE__); \ | ||
230 | } | ||
237 | 231 | ||
238 | // array of 7 thread priority values, hand-tuned by platform so that we offer a uniform [-3,+3] public priority range | 232 | // array of 7 thread priority values, hand-tuned by platform so that we offer a uniform [-3,+3] public priority range |
239 | static int const gs_prio_remap[] = | 233 | static int const gs_prio_remap[] = { |
240 | { | 234 | // NB: PThreads priority handling is about as twisty as one can get it |
241 | // NB: PThreads priority handling is about as twisty as one can get it | 235 | // (and then some). DON*T TRUST ANYTHING YOU READ ON THE NET!!! |
242 | // (and then some). DON*T TRUST ANYTHING YOU READ ON THE NET!!! | 236 | |
243 | 237 | //--- | |
244 | //--- | 238 | // "Select the scheduling policy for the thread: one of SCHED_OTHER |
245 | // "Select the scheduling policy for the thread: one of SCHED_OTHER | 239 | // (regular, non-real-time scheduling), SCHED_RR (real-time, |
246 | // (regular, non-real-time scheduling), SCHED_RR (real-time, | 240 | // round-robin) or SCHED_FIFO (real-time, first-in first-out)." |
247 | // round-robin) or SCHED_FIFO (real-time, first-in first-out)." | 241 | // |
248 | // | 242 | // "Using the RR policy ensures that all threads having the same |
249 | // "Using the RR policy ensures that all threads having the same | 243 | // priority level will be scheduled equally, regardless of their activity." |
250 | // priority level will be scheduled equally, regardless of their activity." | 244 | // |
251 | // | 245 | // "For SCHED_FIFO and SCHED_RR, the only required member of the |
252 | // "For SCHED_FIFO and SCHED_RR, the only required member of the | 246 | // sched_param structure is the priority sched_priority. For SCHED_OTHER, |
253 | // sched_param structure is the priority sched_priority. For SCHED_OTHER, | 247 | // the affected scheduling parameters are implementation-defined." |
254 | // the affected scheduling parameters are implementation-defined." | 248 | // |
255 | // | 249 | // "The priority of a thread is specified as a delta which is added to |
256 | // "The priority of a thread is specified as a delta which is added to | 250 | // the priority of the process." |
257 | // the priority of the process." | 251 | // |
258 | // | 252 | // ".. priority is an integer value, in the range from 1 to 127. |
259 | // ".. priority is an integer value, in the range from 1 to 127. | 253 | // 1 is the least-favored priority, 127 is the most-favored." |
260 | // 1 is the least-favored priority, 127 is the most-favored." | 254 | // |
261 | // | 255 | // "Priority level 0 cannot be used: it is reserved for the system." |
262 | // "Priority level 0 cannot be used: it is reserved for the system." | 256 | // |
263 | // | 257 | // "When you use specify a priority of -99 in a call to |
264 | // "When you use specify a priority of -99 in a call to | 258 | // pthread_setschedparam(), the priority of the target thread is |
265 | // pthread_setschedparam(), the priority of the target thread is | 259 | // lowered to the lowest possible value." |
266 | // lowered to the lowest possible value." | 260 | // |
267 | // | 261 | // ... |
268 | // ... | ||
269 | |||
270 | // ** CONCLUSION ** | ||
271 | // | ||
272 | // PThread priorities are _hugely_ system specific, and we need at | ||
273 | // least OS specific settings. Hopefully, Linuxes and OS X versions | ||
274 | // are uniform enough, among each other... | ||
275 | // | ||
276 | # if defined PLATFORM_OSX | ||
277 | // AK 10-Apr-07 (OS X PowerPC 10.4.9): | ||
278 | // | ||
279 | // With SCHED_RR, 26 seems to be the "normal" priority, where setting | ||
280 | // it does not seem to affect the order of threads processed. | ||
281 | // | ||
282 | // With SCHED_OTHER, the range 25..32 is normal (maybe the same 26, | ||
283 | // but the difference is not so clear with OTHER). | ||
284 | // | ||
285 | // 'sched_get_priority_min()' and '..max()' give 15, 47 as the | ||
286 | // priority limits. This could imply, user mode applications won't | ||
287 | // be able to use values outside of that range. | ||
288 | // | ||
289 | # define _PRIO_MODE SCHED_OTHER | ||
290 | |||
291 | // OS X 10.4.9 (PowerPC) gives ENOTSUP for process scope | ||
292 | //#define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS | ||
293 | |||
294 | # define _PRIO_HI 32 // seems to work (_carefully_ picked!) | ||
295 | # define _PRIO_0 26 // detected | ||
296 | # define _PRIO_LO 1 // seems to work (tested) | ||
297 | |||
298 | # elif defined PLATFORM_LINUX | ||
299 | // (based on Ubuntu Linux 2.6.15 kernel) | ||
300 | // | ||
301 | // SCHED_OTHER is the default policy, but does not allow for priorities. | ||
302 | // SCHED_RR allows priorities, all of which (1..99) are higher than | ||
303 | // a thread with SCHED_OTHER policy. | ||
304 | // | ||
305 | // <http://kerneltrap.org/node/6080> | ||
306 | // <http://en.wikipedia.org/wiki/Native_POSIX_Thread_Library> | ||
307 | // <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html> | ||
308 | // | ||
309 | // Manuals suggest checking #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING, | ||
310 | // but even Ubuntu does not seem to define it. | ||
311 | // | ||
312 | # define _PRIO_MODE SCHED_RR | ||
313 | |||
314 | // NTLP 2.5: only system scope allowed (being the basic reason why | ||
315 | // root privileges are required..) | ||
316 | //#define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS | ||
317 | |||
318 | # define _PRIO_HI 99 | ||
319 | # define _PRIO_0 50 | ||
320 | # define _PRIO_LO 1 | ||
321 | |||
322 | # elif defined(PLATFORM_BSD) | ||
323 | // | ||
324 | // <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html> | ||
325 | // | ||
326 | // "When control over the thread scheduling is desired, then FreeBSD | ||
327 | // with the libpthread implementation is by far the best choice .." | ||
328 | // | ||
329 | # define _PRIO_MODE SCHED_OTHER | ||
330 | # define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS | ||
331 | # define _PRIO_HI 31 | ||
332 | # define _PRIO_0 15 | ||
333 | # define _PRIO_LO 1 | ||
334 | |||
335 | # elif defined(PLATFORM_CYGWIN) | ||
336 | // | ||
337 | // TBD: Find right values for Cygwin | ||
338 | // | ||
339 | # else | ||
340 | # error "Unknown OS: not implemented!" | ||
341 | # endif | ||
342 | 262 | ||
343 | #if defined _PRIO_0 | 263 | // ** CONCLUSION ** |
344 | # define _PRIO_AN (_PRIO_0 + ((_PRIO_HI-_PRIO_0)/2)) | 264 | // |
345 | # define _PRIO_BN (_PRIO_LO + ((_PRIO_0-_PRIO_LO)/2)) | 265 | // PThread priorities are _hugely_ system specific, and we need at |
266 | // least OS specific settings. Hopefully, Linuxes and OS X versions | ||
267 | // are uniform enough, among each other... | ||
268 | // | ||
269 | #if defined PLATFORM_OSX | ||
270 | // AK 10-Apr-07 (OS X PowerPC 10.4.9): | ||
271 | // | ||
272 | // With SCHED_RR, 26 seems to be the "normal" priority, where setting | ||
273 | // it does not seem to affect the order of threads processed. | ||
274 | // | ||
275 | // With SCHED_OTHER, the range 25..32 is normal (maybe the same 26, | ||
276 | // but the difference is not so clear with OTHER). | ||
277 | // | ||
278 | // 'sched_get_priority_min()' and '..max()' give 15, 47 as the | ||
279 | // priority limits. This could imply, user mode applications won't | ||
280 | // be able to use values outside of that range. | ||
281 | // | ||
282 | #define _PRIO_MODE SCHED_OTHER | ||
283 | |||
284 | // OS X 10.4.9 (PowerPC) gives ENOTSUP for process scope | ||
285 | // #define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS | ||
286 | |||
287 | #define _PRIO_HI 32 // seems to work (_carefully_ picked!) | ||
288 | #define _PRIO_0 26 // detected | ||
289 | #define _PRIO_LO 1 // seems to work (tested) | ||
290 | |||
291 | #elif defined PLATFORM_LINUX | ||
292 | // (based on Ubuntu Linux 2.6.15 kernel) | ||
293 | // | ||
294 | // SCHED_OTHER is the default policy, but does not allow for priorities. | ||
295 | // SCHED_RR allows priorities, all of which (1..99) are higher than | ||
296 | // a thread with SCHED_OTHER policy. | ||
297 | // | ||
298 | // <http://kerneltrap.org/node/6080> | ||
299 | // <http://en.wikipedia.org/wiki/Native_POSIX_Thread_Library> | ||
300 | // <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html> | ||
301 | // | ||
302 | // Manuals suggest checking #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING, | ||
303 | // but even Ubuntu does not seem to define it. | ||
304 | // | ||
305 | #define _PRIO_MODE SCHED_RR | ||
346 | 306 | ||
347 | _PRIO_LO, _PRIO_LO, _PRIO_BN, _PRIO_0, _PRIO_AN, _PRIO_HI, _PRIO_HI | 307 | // NTLP 2.5: only system scope allowed (being the basic reason why |
308 | // root privileges are required..) | ||
309 | // #define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS | ||
310 | |||
311 | #define _PRIO_HI 99 | ||
312 | #define _PRIO_0 50 | ||
313 | #define _PRIO_LO 1 | ||
314 | |||
315 | #elif defined(PLATFORM_BSD) | ||
316 | // | ||
317 | // <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html> | ||
318 | // | ||
319 | // "When control over the thread scheduling is desired, then FreeBSD | ||
320 | // with the libpthread implementation is by far the best choice .." | ||
321 | // | ||
322 | #define _PRIO_MODE SCHED_OTHER | ||
323 | #define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS | ||
324 | #define _PRIO_HI 31 | ||
325 | #define _PRIO_0 15 | ||
326 | #define _PRIO_LO 1 | ||
327 | |||
328 | #elif defined(PLATFORM_CYGWIN) | ||
329 | // | ||
330 | // TBD: Find right values for Cygwin | ||
331 | // | ||
332 | #else | ||
333 | #error "Unknown OS: not implemented!" | ||
334 | #endif | ||
335 | |||
336 | #if defined _PRIO_0 | ||
337 | #define _PRIO_AN (_PRIO_0 + ((_PRIO_HI - _PRIO_0) / 2)) | ||
338 | #define _PRIO_BN (_PRIO_LO + ((_PRIO_0 - _PRIO_LO) / 2)) | ||
339 | |||
340 | _PRIO_LO, | ||
341 | _PRIO_LO, | ||
342 | _PRIO_BN, | ||
343 | _PRIO_0, | ||
344 | _PRIO_AN, | ||
345 | _PRIO_HI, | ||
346 | _PRIO_HI | ||
348 | #endif // _PRIO_0 | 347 | #endif // _PRIO_0 |
349 | }; | 348 | }; |
350 | 349 | ||
@@ -398,10 +397,8 @@ void THREAD_SET_AFFINITY(unsigned int aff) | |||
398 | cpu_set_t cpuset; | 397 | cpu_set_t cpuset; |
399 | CPU_ZERO(&cpuset); | 398 | CPU_ZERO(&cpuset); |
400 | #endif | 399 | #endif |
401 | while (aff != 0) | 400 | while (aff != 0) { |
402 | { | 401 | if (aff & 1) { |
403 | if (aff & 1) | ||
404 | { | ||
405 | CPU_SET(bit, &cpuset); | 402 | CPU_SET(bit, &cpuset); |
406 | } | 403 | } |
407 | ++bit; | 404 | ++bit; |
@@ -430,7 +427,7 @@ void THREAD_SETNAME(char const* _name) | |||
430 | #elif defined PLATFORM_LINUX | 427 | #elif defined PLATFORM_LINUX |
431 | #if LINUX_USE_PTHREAD_SETNAME_NP | 428 | #if LINUX_USE_PTHREAD_SETNAME_NP |
432 | pthread_setname_np(pthread_self(), _name); | 429 | pthread_setname_np(pthread_self(), _name); |
433 | #else // LINUX_USE_PTHREAD_SETNAME_NP | 430 | #else // LINUX_USE_PTHREAD_SETNAME_NP |
434 | prctl(PR_SET_NAME, _name, 0, 0, 0); | 431 | prctl(PR_SET_NAME, _name, 0, 0, 0); |
435 | #endif // LINUX_USE_PTHREAD_SETNAME_NP | 432 | #endif // LINUX_USE_PTHREAD_SETNAME_NP |
436 | #elif defined PLATFORM_QNX || defined PLATFORM_CYGWIN | 433 | #elif defined PLATFORM_QNX || defined PLATFORM_CYGWIN |