diff options
-rw-r--r-- | CHANGES | 5 | ||||
-rw-r--r-- | docs/index.html | 26 | ||||
-rw-r--r-- | src/lanes.c | 31 | ||||
-rw-r--r-- | src/lanes.lua | 1 | ||||
-rw-r--r-- | src/threading.c | 108 | ||||
-rw-r--r-- | src/threading.h | 84 |
6 files changed, 161 insertions, 94 deletions
@@ -1,5 +1,10 @@ | |||
1 | CHANGES: | 1 | CHANGES: |
2 | 2 | ||
3 | CHANGE 86: BGe 3-Dec-13 | ||
4 | * version 3.7.4 | ||
5 | * internal refactoring of pthread priority management code | ||
6 | * new API lanes.set_thread_priority() | ||
7 | |||
3 | CHANGE 85: BGe 28-Nov-13 | 8 | CHANGE 85: BGe 28-Nov-13 |
4 | * version 3.7.3 | 9 | * version 3.7.3 |
5 | * set pthread thread cancel type to PTHREAD_CANCEL_ASYNCHRONOUS | 10 | * set pthread thread cancel type to PTHREAD_CANCEL_ASYNCHRONOUS |
diff --git a/docs/index.html b/docs/index.html index f50f342..af08397 100644 --- a/docs/index.html +++ b/docs/index.html | |||
@@ -70,7 +70,7 @@ | |||
70 | </p> | 70 | </p> |
71 | 71 | ||
72 | <p> | 72 | <p> |
73 | This document was revised on 28-Nov-13, and applies to version <tt>3.7.3</tt>. | 73 | This document was revised on 3-Dec-13, and applies to version <tt>3.7.4</tt>. |
74 | </p> | 74 | </p> |
75 | </font> | 75 | </font> |
76 | </center> | 76 | </center> |
@@ -537,7 +537,7 @@ | |||
537 | </p> | 537 | </p> |
538 | 538 | ||
539 | <p> | 539 | <p> |
540 | <code>opt_tbl</code> is a collection of named options to control the way lanes are run: | 540 | <code id="generator_settings">opt_tbl</code> is a collection of named options to control the way lanes are run: |
541 | </p> | 541 | </p> |
542 | 542 | ||
543 | <p> | 543 | <p> |
@@ -554,7 +554,7 @@ | |||
554 | </td> | 554 | </td> |
555 | <td>integer >= 1/<tt>true</tt></td> | 555 | <td>integer >= 1/<tt>true</tt></td> |
556 | <td> | 556 | <td> |
557 | By default, lanes are only cancellable when they <u>enter</u> a pending <tt>:receive()</tt> or <tt>:send()</tt> call. With this option, one can set <a href="#cancelling">cancellation</a> check to occur every <tt>N</tt> Lua statements. The value <tt>true</tt> uses a default value (100). | 557 | By default, lanes are only cancellable when they <u>enter</u> a pending <tt>:receive()</tt> or <tt>:send()</tt> call. With this option, one can set <a href="#cancelling">cancellation</a> check to occur every <tt>N</tt> Lua statements through the line hook facility. The value <tt>true</tt> uses a default value (100). |
558 | It is also possible to manually test for cancel requests with <tt>cancel_test()</tt>. | 558 | It is also possible to manually test for cancel requests with <tt>cancel_test()</tt>. |
559 | </td> | 559 | </td> |
560 | </tr> | 560 | </tr> |
@@ -593,6 +593,8 @@ | |||
593 | These values are a mapping over the actual priority range of the underlying implementation. | 593 | These values are a mapping over the actual priority range of the underlying implementation. |
594 | <br> | 594 | <br> |
595 | Implementation and dependability of priorities varies by platform. Especially Linux kernel 2.6 is not supporting priorities in user mode. | 595 | Implementation and dependability of priorities varies by platform. Especially Linux kernel 2.6 is not supporting priorities in user mode. |
596 | <br> | ||
597 | A lane can also change its own thread priority dynamically with <a href="#priority"><tt>lanes.set_thread_priority()</tt></a>. | ||
596 | </td> | 598 | </td> |
597 | </tr> | 599 | </tr> |
598 | <tr valign=top> | 600 | <tr valign=top> |
@@ -644,6 +646,24 @@ | |||
644 | </p> | 646 | </p> |
645 | 647 | ||
646 | 648 | ||
649 | <!-- priority +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | ||
650 | <hr/> | ||
651 | <h2 id="priority">Priority</h2> | ||
652 | |||
653 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"> | ||
654 | <tr> | ||
655 | <td> | ||
656 | <pre> lanes.set_thread_priority( prio)</pre> | ||
657 | </td> | ||
658 | </tr> | ||
659 | </table> | ||
660 | <p> | ||
661 | Besides setting a default priority in the generator <a href="#generator_settings">settings</a>, each thread can change its own priority at will. This is also true for the main Lua state. | ||
662 | <br> | ||
663 | The priority must be in the range <tt>[-3,+3]</tt>. | ||
664 | </p> | ||
665 | |||
666 | |||
647 | <!-- status +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> | 667 | <!-- status +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> |
648 | <hr/> | 668 | <hr/> |
649 | <h2 id="status">Status</h2> | 669 | <h2 id="status">Status</h2> |
diff --git a/src/lanes.c b/src/lanes.c index ec7fd9e..467c920 100644 --- a/src/lanes.c +++ b/src/lanes.c | |||
@@ -35,10 +35,10 @@ | |||
35 | * | 35 | * |
36 | * Defines: | 36 | * Defines: |
37 | * -DLINUX_SCHED_RR: all threads are lifted to SCHED_RR category, to | 37 | * -DLINUX_SCHED_RR: all threads are lifted to SCHED_RR category, to |
38 | * allow negative priorities (-2,-1) be used. Even without this, | 38 | * allow negative priorities [-3,-1] be used. Even without this, |
39 | * using priorities will require 'sudo' privileges on Linux. | 39 | * using priorities will require 'sudo' privileges on Linux. |
40 | * | 40 | * |
41 | * -DUSE_PTHREAD_TIMEDJOIN: use 'pthread_timedjoin_np()' for waiting | 41 | * -DUSE_PTHREAD_TIMEDJOIN: use 'pthread_timedjoin_np()' for waiting |
42 | * for threads with a timeout. This changes the thread cleanup | 42 | * for threads with a timeout. This changes the thread cleanup |
43 | * mechanism slightly (cleans up at the join, not once the thread | 43 | * mechanism slightly (cleans up at the join, not once the thread |
44 | * has finished). May or may not be a good idea to use it. | 44 | * has finished). May or may not be a good idea to use it. |
@@ -52,7 +52,7 @@ | |||
52 | * ... | 52 | * ... |
53 | */ | 53 | */ |
54 | 54 | ||
55 | char const* VERSION = "3.7.3"; | 55 | char const* VERSION = "3.7.4"; |
56 | 56 | ||
57 | /* | 57 | /* |
58 | =============================================================================== | 58 | =============================================================================== |
@@ -1734,6 +1734,20 @@ LUAG_FUNC( set_debug_threadname) | |||
1734 | return 0; | 1734 | return 0; |
1735 | } | 1735 | } |
1736 | 1736 | ||
1737 | LUAG_FUNC( set_thread_priority) | ||
1738 | { | ||
1739 | int const prio = luaL_checkint( L, 1); | ||
1740 | // public Lanes API accepts a generic range -3/+3 | ||
1741 | // that will be remapped into the platform-specific scheduler priority scheme | ||
1742 | // On some platforms, -3 is equivalent to -2 and +3 to +2 | ||
1743 | if( prio < THREAD_PRIO_MIN || prio > THREAD_PRIO_MAX) | ||
1744 | { | ||
1745 | return luaL_error( L, "priority out of range: %d..+%d (%d)", THREAD_PRIO_MIN, THREAD_PRIO_MAX, prio); | ||
1746 | } | ||
1747 | THREAD_SET_PRIORITY( prio); | ||
1748 | return 0; | ||
1749 | } | ||
1750 | |||
1737 | #if USE_DEBUG_SPEW | 1751 | #if USE_DEBUG_SPEW |
1738 | // can't use direct LUA_x errcode indexing because the sequence is not the same between Lua 5.1 and 5.2 :-( | 1752 | // can't use direct LUA_x errcode indexing because the sequence is not the same between Lua 5.1 and 5.2 :-( |
1739 | // LUA_ERRERR doesn't have the same value | 1753 | // LUA_ERRERR doesn't have the same value |
@@ -2693,6 +2707,7 @@ static const struct luaL_Reg lanes_functions [] = { | |||
2693 | {"linda", LG_linda}, | 2707 | {"linda", LG_linda}, |
2694 | {"now_secs", LG_now_secs}, | 2708 | {"now_secs", LG_now_secs}, |
2695 | {"wakeup_conv", LG_wakeup_conv}, | 2709 | {"wakeup_conv", LG_wakeup_conv}, |
2710 | {"set_thread_priority", LG_set_thread_priority}, | ||
2696 | {"nameof", luaG_nameof}, | 2711 | {"nameof", luaG_nameof}, |
2697 | {"set_singlethreaded", LG_set_singlethreaded}, | 2712 | {"set_singlethreaded", LG_set_singlethreaded}, |
2698 | {NULL, NULL} | 2713 | {NULL, NULL} |
@@ -2754,16 +2769,18 @@ static void init_once_LOCKED( lua_State* L) | |||
2754 | // be enabled also for Linux. | 2769 | // be enabled also for Linux. |
2755 | // | 2770 | // |
2756 | #ifdef PLATFORM_LINUX | 2771 | #ifdef PLATFORM_LINUX |
2757 | sudo= geteuid()==0; // we are root? | 2772 | sudo = (geteuid() == 0); // we are root? |
2758 | 2773 | ||
2759 | // If lower priorities (-2..-1) are wanted, we need to lift the main | 2774 | // If lower priorities (-2..-1) are wanted, we need to lift the main |
2760 | // thread to SCHED_RR and 50 (medium) level. Otherwise, we're always below | 2775 | // thread to SCHED_RR and 50 (medium) level. Otherwise, we're always below |
2761 | // the launched threads (even -2). | 2776 | // the launched threads (even -2). |
2762 | // | 2777 | // |
2763 | #ifdef LINUX_SCHED_RR | 2778 | #ifdef LINUX_SCHED_RR |
2764 | if (sudo) { | 2779 | if( sudo) |
2765 | struct sched_param sp= {0}; sp.sched_priority= _PRIO_0; | 2780 | { |
2766 | PT_CALL( pthread_setschedparam( pthread_self(), SCHED_RR, &sp) ); | 2781 | struct sched_param sp; |
2782 | sp.sched_priority = _PRIO_0; | ||
2783 | PT_CALL( pthread_setschedparam( pthread_self(), SCHED_RR, &sp)); | ||
2767 | } | 2784 | } |
2768 | #endif // LINUX_SCHED_RR | 2785 | #endif // LINUX_SCHED_RR |
2769 | #endif // PLATFORM_LINUX | 2786 | #endif // PLATFORM_LINUX |
diff --git a/src/lanes.lua b/src/lanes.lua index 1b81944..6e2a736 100644 --- a/src/lanes.lua +++ b/src/lanes.lua | |||
@@ -683,6 +683,7 @@ end | |||
683 | lanes.cancel_error = core.cancel_error | 683 | lanes.cancel_error = core.cancel_error |
684 | lanes.nameof = core.nameof | 684 | lanes.nameof = core.nameof |
685 | lanes.threads = core.threads or function() error "lane tracking is not available" end -- core.threads isn't registered if settings.track_lanes is false | 685 | lanes.threads = core.threads or function() error "lane tracking is not available" end -- core.threads isn't registered if settings.track_lanes is false |
686 | lanes.set_thread_priority = core.set_thread_priority | ||
686 | lanes.timer = timer | 687 | lanes.timer = timer |
687 | lanes.timer_lane = timer_lane | 688 | lanes.timer_lane = timer_lane |
688 | lanes.timers = timers | 689 | lanes.timers = timers |
diff --git a/src/threading.c b/src/threading.c index 18eef87..db9f734 100644 --- a/src/threading.c +++ b/src/threading.c | |||
@@ -12,6 +12,7 @@ | |||
12 | =============================================================================== | 12 | =============================================================================== |
13 | 13 | ||
14 | Copyright (C) 2007-10 Asko Kauppi <akauppi@gmail.com> | 14 | Copyright (C) 2007-10 Asko Kauppi <akauppi@gmail.com> |
15 | Copyright (C) 2009-13, Benoit Germain <bnt.germain@gmail.com> | ||
15 | 16 | ||
16 | Permission is hereby granted, free of charge, to any person obtaining a copy | 17 | Permission is hereby granted, free of charge, to any person obtaining a copy |
17 | of this software and associated documentation files (the "Software"), to deal | 18 | of this software and associated documentation files (the "Software"), to deal |
@@ -269,40 +270,52 @@ static void prepare_timeout( struct timespec *ts, time_d abs_secs ) { | |||
269 | } | 270 | } |
270 | #endif // Windows NT4 | 271 | #endif // Windows NT4 |
271 | 272 | ||
272 | /* MSDN: "If you would like to use the CRT in ThreadProc, use the | 273 | static int const gs_prio_remap[] = |
273 | _beginthreadex function instead (of CreateThread)." | 274 | { |
274 | MSDN: "you can create at most 2028 threads" | 275 | THREAD_PRIORITY_IDLE, |
275 | */ | 276 | THREAD_PRIORITY_LOWEST, |
276 | void | 277 | THREAD_PRIORITY_BELOW_NORMAL, |
277 | THREAD_CREATE( THREAD_T *ref, | 278 | THREAD_PRIORITY_NORMAL, |
278 | THREAD_RETURN_T (__stdcall *func)( void * ), | 279 | THREAD_PRIORITY_ABOVE_NORMAL, |
279 | // Note: Visual C++ requires '__stdcall' where it is | 280 | THREAD_PRIORITY_HIGHEST, |
280 | void *data, int prio /* -3..+3 */ ) { | 281 | THREAD_PRIORITY_TIME_CRITICAL |
281 | 282 | }; | |
282 | HANDLE h= (HANDLE)_beginthreadex( NULL, // security | 283 | |
283 | _THREAD_STACK_SIZE, | 284 | /* MSDN: "If you would like to use the CRT in ThreadProc, use the |
284 | func, | 285 | _beginthreadex function instead (of CreateThread)." |
285 | data, | 286 | MSDN: "you can create at most 2028 threads" |
286 | 0, // flags (0/CREATE_SUSPENDED) | 287 | */ |
287 | NULL // thread id (not used) | 288 | // Note: Visual C++ requires '__stdcall' where it is |
288 | ); | 289 | void THREAD_CREATE( THREAD_T* ref, THREAD_RETURN_T (__stdcall *func)( void*), void* data, int prio /* -3..+3 */) |
289 | 290 | { | |
290 | if (h == INVALID_HANDLE_VALUE) FAIL( "CreateThread", GetLastError() ); | 291 | HANDLE h = (HANDLE) _beginthreadex( NULL, // security |
291 | 292 | _THREAD_STACK_SIZE, | |
292 | if (prio!= 0) { | 293 | func, |
293 | int win_prio= (prio == +3) ? THREAD_PRIORITY_TIME_CRITICAL : | 294 | data, |
294 | (prio == +2) ? THREAD_PRIORITY_HIGHEST : | 295 | 0, // flags (0/CREATE_SUSPENDED) |
295 | (prio == +1) ? THREAD_PRIORITY_ABOVE_NORMAL : | 296 | NULL // thread id (not used) |
296 | (prio == -1) ? THREAD_PRIORITY_BELOW_NORMAL : | 297 | ); |
297 | (prio == -2) ? THREAD_PRIORITY_LOWEST : | 298 | |
298 | THREAD_PRIORITY_IDLE; // -3 | 299 | if( h == INVALID_HANDLE_VALUE) |
299 | 300 | FAIL( "CreateThread", GetLastError()); | |
300 | if (!SetThreadPriority( h, win_prio )) | 301 | |
301 | FAIL( "SetThreadPriority", GetLastError() ); | 302 | if (!SetThreadPriority( h, gs_prio_remap[prio + 3])) |
302 | } | 303 | FAIL( "SetThreadPriority", GetLastError()); |
303 | *ref= h; | 304 | |
304 | } | 305 | *ref = h; |
305 | // | 306 | } |
307 | |||
308 | |||
309 | void THREAD_SET_PRIORITY( int prio) | ||
310 | { | ||
311 | // prio range [-3,+3] was checked by the caller | ||
312 | if (!SetThreadPriority( GetCurrentThread(), gs_prio_remap[prio + 3])) | ||
313 | { | ||
314 | FAIL( "THREAD_SET_PRIORITY", GetLastError()); | ||
315 | } | ||
316 | } | ||
317 | |||
318 | |||
306 | bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs) | 319 | bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs) |
307 | { | 320 | { |
308 | DWORD ms = (secs<0.0) ? INFINITE : (DWORD)((secs*1000.0)+0.5); | 321 | DWORD ms = (secs<0.0) ? INFINITE : (DWORD)((secs*1000.0)+0.5); |
@@ -710,20 +723,19 @@ static int const gs_prio_remap[] = | |||
710 | # endif | 723 | # endif |
711 | 724 | ||
712 | #if defined _PRIO_0 | 725 | #if defined _PRIO_0 |
713 | # define _PRIO_AN (_PRIO_0 + ((_PRIO_HI-_PRIO_0)/2) ) | 726 | # define _PRIO_AN (_PRIO_0 + ((_PRIO_HI-_PRIO_0)/2)) |
714 | # define _PRIO_BN (_PRIO_LO + ((_PRIO_0-_PRIO_LO)/2) ) | 727 | # define _PRIO_BN (_PRIO_LO + ((_PRIO_0-_PRIO_LO)/2)) |
715 | 728 | ||
716 | _PRIO_LO, _PRIO_LO, _PRIO_BN, _PRIO_0, _PRIO_AN, _PRIO_HI, _PRIO_HI | 729 | _PRIO_LO, _PRIO_LO, _PRIO_BN, _PRIO_0, _PRIO_AN, _PRIO_HI, _PRIO_HI |
717 | #endif // _PRIO_0 | 730 | #endif // _PRIO_0 |
718 | }; | 731 | }; |
719 | 732 | ||
720 | // | 733 | void THREAD_CREATE( THREAD_T* ref, THREAD_RETURN_T (*func)( void*), void* data, int prio /* -3..+3 */) |
721 | void THREAD_CREATE( THREAD_T* ref, THREAD_RETURN_T (*func)( void * ), void *data, int prio /* -2..+2 */) | ||
722 | { | 734 | { |
723 | pthread_attr_t a; | 735 | pthread_attr_t a; |
724 | bool_t const normal = | 736 | bool_t const normal = |
725 | #if defined(PLATFORM_LINUX) && defined(LINUX_SCHED_RR) | 737 | #if defined(PLATFORM_LINUX) && defined(LINUX_SCHED_RR) |
726 | !sudo; // with sudo, even normal thread must use SCHED_RR | 738 | !sudo; // with sudo, even normal thread must use SCHED_RR |
727 | #else | 739 | #else |
728 | (prio == 0); | 740 | (prio == 0); |
729 | #endif | 741 | #endif |
@@ -762,7 +774,6 @@ void THREAD_CREATE( THREAD_T* ref, THREAD_RETURN_T (*func)( void * ), void *data | |||
762 | // | 774 | // |
763 | PT_CALL( pthread_attr_setinheritsched( &a, PTHREAD_EXPLICIT_SCHED)); | 775 | PT_CALL( pthread_attr_setinheritsched( &a, PTHREAD_EXPLICIT_SCHED)); |
764 | 776 | ||
765 | |||
766 | #ifdef _PRIO_SCOPE | 777 | #ifdef _PRIO_SCOPE |
767 | PT_CALL( pthread_attr_setscope( &a, _PRIO_SCOPE)); | 778 | PT_CALL( pthread_attr_setscope( &a, _PRIO_SCOPE)); |
768 | #endif // _PRIO_SCOPE | 779 | #endif // _PRIO_SCOPE |
@@ -828,13 +839,28 @@ void THREAD_CREATE( THREAD_T* ref, THREAD_RETURN_T (*func)( void * ), void *data | |||
828 | PT_CALL( pthread_attr_destroy( &a)); | 839 | PT_CALL( pthread_attr_destroy( &a)); |
829 | } | 840 | } |
830 | 841 | ||
842 | |||
843 | void THREAD_SET_PRIORITY( int prio) | ||
844 | { | ||
845 | #if defined PLATFORM_LINUX && defined LINUX_SCHED_RR | ||
846 | if( sudo) // only root-privileged process can change priorities | ||
847 | #endif // defined PLATFORM_LINUX && defined LINUX_SCHED_RR | ||
848 | { | ||
849 | struct sched_param sp; | ||
850 | // prio range [-3,+3] was checked by the caller | ||
851 | sp.sched_priority = gs_prio_remap[ prio + 3]; | ||
852 | PT_CALL( pthread_setschedparam( pthread_self(), _PRIO_MODE, &sp)); | ||
853 | } | ||
854 | } | ||
855 | |||
856 | |||
831 | /* | 857 | /* |
832 | * Wait for a thread to finish. | 858 | * Wait for a thread to finish. |
833 | * | 859 | * |
834 | * 'mu_ref' is a lock we should use for the waiting; initially unlocked. | 860 | * 'mu_ref' is a lock we should use for the waiting; initially unlocked. |
835 | * Same lock as passed to THREAD_EXIT. | 861 | * Same lock as passed to THREAD_EXIT. |
836 | * | 862 | * |
837 | * Returns TRUE for succesful wait, FALSE for timed out | 863 | * Returns TRUE for successful wait, FALSE for timed out |
838 | */ | 864 | */ |
839 | bool_t THREAD_WAIT( THREAD_T *ref, double secs , SIGNAL_T *signal_ref, MUTEX_T *mu_ref, volatile enum e_status *st_ref) | 865 | bool_t THREAD_WAIT( THREAD_T *ref, double secs , SIGNAL_T *signal_ref, MUTEX_T *mu_ref, volatile enum e_status *st_ref) |
840 | { | 866 | { |
diff --git a/src/threading.h b/src/threading.h index d87bba6..0698355 100644 --- a/src/threading.h +++ b/src/threading.h | |||
@@ -184,26 +184,25 @@ bool_t SIGNAL_WAIT( SIGNAL_T *ref, MUTEX_T *mu, time_d timeout ); | |||
184 | 184 | ||
185 | #if THREADAPI == THREADAPI_WINDOWS | 185 | #if THREADAPI == THREADAPI_WINDOWS |
186 | 186 | ||
187 | typedef HANDLE THREAD_T; | 187 | typedef HANDLE THREAD_T; |
188 | # define THREAD_ISNULL( _h) (_h == 0) | 188 | # define THREAD_ISNULL( _h) (_h == 0) |
189 | // | 189 | void THREAD_CREATE( THREAD_T* ref, THREAD_RETURN_T (__stdcall *func)( void*), void* data, int prio /* -3..+3 */); |
190 | void THREAD_CREATE( THREAD_T *ref, | ||
191 | THREAD_RETURN_T (__stdcall *func)( void * ), | ||
192 | void *data, int prio /* -3..+3 */ ); | ||
193 | 190 | ||
194 | # define THREAD_PRIO_MIN (-3) | 191 | # define THREAD_PRIO_MIN (-3) |
195 | # define THREAD_PRIO_MAX (+3) | 192 | # define THREAD_PRIO_MAX (+3) |
196 | 193 | ||
197 | #define THREAD_CLEANUP_PUSH( cb_, val_) | 194 | # define THREAD_CLEANUP_PUSH( cb_, val_) |
198 | #define THREAD_CLEANUP_POP( execute_) | 195 | # define THREAD_CLEANUP_POP( execute_) |
199 | 196 | ||
200 | #else // THREADAPI == THREADAPI_PTHREAD | 197 | #else // THREADAPI == THREADAPI_PTHREAD |
201 | /* Platforms that have a timed 'pthread_join()' can get away with a simpler | 198 | |
202 | * implementation. Others will use a condition variable. | 199 | /* Platforms that have a timed 'pthread_join()' can get away with a simpler |
203 | */ | 200 | * implementation. Others will use a condition variable. |
204 | #if defined __WINPTHREADS_VERSION | 201 | */ |
205 | //#define USE_PTHREAD_TIMEDJOIN | 202 | # if defined __WINPTHREADS_VERSION |
206 | #endif // __WINPTHREADS_VERSION | 203 | //# define USE_PTHREAD_TIMEDJOIN |
204 | # endif // __WINPTHREADS_VERSION | ||
205 | |||
207 | # ifdef USE_PTHREAD_TIMEDJOIN | 206 | # ifdef USE_PTHREAD_TIMEDJOIN |
208 | # ifdef PLATFORM_OSX | 207 | # ifdef PLATFORM_OSX |
209 | # error "No 'pthread_timedjoin()' on this system" | 208 | # error "No 'pthread_timedjoin()' on this system" |
@@ -213,33 +212,31 @@ bool_t SIGNAL_WAIT( SIGNAL_T *ref, MUTEX_T *mu, time_d timeout ); | |||
213 | # endif | 212 | # endif |
214 | # endif | 213 | # endif |
215 | 214 | ||
216 | typedef pthread_t THREAD_T; | 215 | typedef pthread_t THREAD_T; |
217 | # define THREAD_ISNULL( _h) 0 // pthread_t may be a structure: never 'null' by itself | 216 | # define THREAD_ISNULL( _h) 0 // pthread_t may be a structure: never 'null' by itself |
218 | 217 | ||
219 | void THREAD_CREATE( THREAD_T *ref, | 218 | void THREAD_CREATE( THREAD_T* ref, THREAD_RETURN_T (*func)( void*), void* data, int prio /* -3..+3 */); |
220 | THREAD_RETURN_T (*func)( void * ), | 219 | |
221 | void *data, int prio /* -2..+2 */ ); | 220 | # if defined(PLATFORM_LINUX) |
222 | 221 | extern volatile bool_t sudo; | |
223 | # if defined(PLATFORM_LINUX) | 222 | # ifdef LINUX_SCHED_RR |
224 | extern volatile bool_t sudo; | 223 | # define THREAD_PRIO_MIN (sudo ? -3 : 0) |
225 | # ifdef LINUX_SCHED_RR | 224 | # else |
226 | # define THREAD_PRIO_MIN (sudo ? -3 : 0) | 225 | # define THREAD_PRIO_MIN (0) |
227 | # else | 226 | # endif |
228 | # define THREAD_PRIO_MIN (0) | 227 | # define THREAD_PRIO_MAX (sudo ? +3 : 0) |
229 | # endif | 228 | # else |
230 | # define THREAD_PRIO_MAX (sudo ? +3 : 0) | 229 | # define THREAD_PRIO_MIN (-3) |
231 | # else | 230 | # define THREAD_PRIO_MAX (+3) |
232 | # define THREAD_PRIO_MIN (-3) | 231 | # endif |
233 | # define THREAD_PRIO_MAX (+3) | 232 | |
234 | # endif | 233 | # if THREADWAIT_METHOD == THREADWAIT_CONDVAR |
235 | 234 | # define THREAD_CLEANUP_PUSH( cb_, val_) pthread_cleanup_push( cb_, val_) | |
236 | #if THREADWAIT_METHOD == THREADWAIT_CONDVAR | 235 | # define THREAD_CLEANUP_POP( execute_) pthread_cleanup_pop( execute_) |
237 | #define THREAD_CLEANUP_PUSH( cb_, val_) pthread_cleanup_push( cb_, val_) | 236 | # else |
238 | #define THREAD_CLEANUP_POP( execute_) pthread_cleanup_pop( execute_) | 237 | # define THREAD_CLEANUP_PUSH( cb_, val_) { |
239 | #else | 238 | # define THREAD_CLEANUP_POP( execute_) } |
240 | #define THREAD_CLEANUP_PUSH( cb_, val_) { | 239 | # endif // THREADWAIT_METHOD == THREADWAIT_CONDVAR |
241 | #define THREAD_CLEANUP_POP( execute_) } | ||
242 | #endif // THREADWAIT_METHOD == THREADWAIT_CONDVAR | ||
243 | #endif // THREADAPI == THREADAPI_WINDOWS | 240 | #endif // THREADAPI == THREADAPI_WINDOWS |
244 | 241 | ||
245 | /* | 242 | /* |
@@ -267,5 +264,6 @@ bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs, SIGNAL_T *signal_ref, MUTEX | |||
267 | void THREAD_KILL( THREAD_T* ref); | 264 | void THREAD_KILL( THREAD_T* ref); |
268 | void THREAD_SETNAME( char const* _name); | 265 | void THREAD_SETNAME( char const* _name); |
269 | void THREAD_MAKE_ASYNCH_CANCELLABLE(); | 266 | void THREAD_MAKE_ASYNCH_CANCELLABLE(); |
267 | void THREAD_SET_PRIORITY( int prio); | ||
270 | 268 | ||
271 | #endif // __threading_h__ | 269 | #endif // __threading_h__ |