aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/index.html2
-rw-r--r--src/lanes.c3
-rw-r--r--src/lanes.lua2
-rw-r--r--src/threading.c428
-rw-r--r--src/threading.h13
5 files changed, 221 insertions, 227 deletions
diff --git a/docs/index.html b/docs/index.html
index 25f9e22..f50f342 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -589,7 +589,7 @@
589 </td> 589 </td>
590 <td>integer</td> 590 <td>integer</td>
591 <td> 591 <td>
592 The priority of lanes generated in the range -3..+3 (MinGW pthread and Windows thread API), or -2..+2 otherwise (default is 0). 592 The priority of lanes generated in the range -3..+3 (default is 0).
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.
diff --git a/src/lanes.c b/src/lanes.c
index 9e32f9a..ec7fd9e 100644
--- a/src/lanes.c
+++ b/src/lanes.c
@@ -1976,8 +1976,9 @@ LUAG_FUNC( thread_new)
1976#define FIXED_ARGS 8 1976#define FIXED_ARGS 8
1977 uint_t args = lua_gettop(L) - FIXED_ARGS; 1977 uint_t args = lua_gettop(L) - FIXED_ARGS;
1978 1978
1979 // public Lanes API accepts a generic range (-3/+3 for windows and MinGW-pthread, -2/+2 for the rest of the world) 1979 // public Lanes API accepts a generic range -3/+3
1980 // that will be remapped into the platform-specific scheduler priority scheme 1980 // that will be remapped into the platform-specific scheduler priority scheme
1981 // On some platforms, -3 is equivalent to -2 and +3 to +2
1981 if( prio < THREAD_PRIO_MIN || prio > THREAD_PRIO_MAX) 1982 if( prio < THREAD_PRIO_MIN || prio > THREAD_PRIO_MAX)
1982 { 1983 {
1983 return luaL_error( L, "Priority out of range: %d..+%d (%d)", THREAD_PRIO_MIN, THREAD_PRIO_MAX, prio); 1984 return luaL_error( L, "Priority out of range: %d..+%d (%d)", THREAD_PRIO_MIN, THREAD_PRIO_MAX, prio);
diff --git a/src/lanes.lua b/src/lanes.lua
index 1a1c252..1b81944 100644
--- a/src/lanes.lua
+++ b/src/lanes.lua
@@ -204,7 +204,7 @@ end
204-- "math,os": math + os + base libraries (named ones + base) 204-- "math,os": math + os + base libraries (named ones + base)
205-- "*": all standard libraries available 205-- "*": all standard libraries available
206-- 206--
207-- 'opt': .priority: int (-2..+2) smaller is lower priority (0 = default) 207-- 'opt': .priority: int (-3..+3) smaller is lower priority (0 = default)
208-- 208--
209-- .cancelstep: bool | uint 209-- .cancelstep: bool | uint
210-- false: cancellation check only at pending Linda operations 210-- false: cancellation check only at pending Linda operations
diff --git a/src/threading.c b/src/threading.c
index d50207e..18eef87 100644
--- a/src/threading.c
+++ b/src/threading.c
@@ -525,7 +525,8 @@ bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs)
525 // 525 //
526 #include <errno.h> 526 #include <errno.h>
527 527
528# if ((defined(__MINGW32__) || defined(__MINGW64__)) && pthread_attr_setschedpolicy( A, S) == ENOTSUP) 528# if (defined(__MINGW32__) || defined(__MINGW64__)) && defined pthread_attr_setschedpolicy
529# if pthread_attr_setschedpolicy( A, S) == ENOTSUP
529 // from the mingw-w64 team: 530 // from the mingw-w64 team:
530 // Well, we support pthread_setschedparam by which you can specify 531 // Well, we support pthread_setschedparam by which you can specify
531 // threading-policy. Nevertheless, yes we lack this function. In 532 // threading-policy. Nevertheless, yes we lack this function. In
@@ -540,6 +541,7 @@ bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs)
540 } 541 }
541 return 0; 542 return 0;
542 } 543 }
544# endif // pthread_attr_setschedpolicy()
543# endif // defined(__MINGW32__) || defined(__MINGW64__) 545# endif // defined(__MINGW32__) || defined(__MINGW64__)
544 546
545 static void _PT_FAIL( int rc, const char *name, const char *file, uint_t line ) { 547 static void _PT_FAIL( int rc, const char *name, const char *file, uint_t line ) {
@@ -593,245 +595,239 @@ bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs)
593 void SIGNAL_ALL( SIGNAL_T *ref ) { 595 void SIGNAL_ALL( SIGNAL_T *ref ) {
594 PT_CALL( pthread_cond_broadcast(ref) ); // wake up ALL waiting threads 596 PT_CALL( pthread_cond_broadcast(ref) ); // wake up ALL waiting threads
595 } 597 }
596 //
597 void THREAD_CREATE( THREAD_T* ref,
598 THREAD_RETURN_T (*func)( void * ),
599 void *data, int prio /* -2..+2 */ ) {
600 pthread_attr_t _a;
601 pthread_attr_t *a= &_a;
602 struct sched_param sp;
603 bool_t normal;
604 598
605 PT_CALL( pthread_attr_init(a) ); 599// array of 7 thread priority values, hand-tuned by platform so that we offer a uniform [-3,+3] public priority range
600static int const gs_prio_remap[] =
601{
602 // NB: PThreads priority handling is about as twisty as one can get it
603 // (and then some). DON*T TRUST ANYTHING YOU READ ON THE NET!!!
606 604
607#ifndef PTHREAD_TIMEDJOIN 605 //---
608 // We create a NON-JOINABLE thread. This is mainly due to the lack of 606 // "Select the scheduling policy for the thread: one of SCHED_OTHER
609 // 'pthread_timedjoin()', but does offer other benefits (s.a. earlier 607 // (regular, non-real-time scheduling), SCHED_RR (real-time,
610 // freeing of the thread's resources). 608 // round-robin) or SCHED_FIFO (real-time, first-in first-out)."
611 // 609 //
612 PT_CALL( pthread_attr_setdetachstate(a,PTHREAD_CREATE_DETACHED) ); 610 // "Using the RR policy ensures that all threads having the same
613#endif 611 // priority level will be scheduled equally, regardless of their activity."
612 //
613 // "For SCHED_FIFO and SCHED_RR, the only required member of the
614 // sched_param structure is the priority sched_priority. For SCHED_OTHER,
615 // the affected scheduling parameters are implementation-defined."
616 //
617 // "The priority of a thread is specified as a delta which is added to
618 // the priority of the process."
619 //
620 // ".. priority is an integer value, in the range from 1 to 127.
621 // 1 is the least-favored priority, 127 is the most-favored."
622 //
623 // "Priority level 0 cannot be used: it is reserved for the system."
624 //
625 // "When you use specify a priority of -99 in a call to
626 // pthread_setschedparam(), the priority of the target thread is
627 // lowered to the lowest possible value."
628 //
629 // ...
614 630
615 // Use this to find a system's default stack size (DEBUG) 631 // ** CONCLUSION **
616#if 0 632 //
617 { size_t n; pthread_attr_getstacksize( a, &n ); 633 // PThread priorities are _hugely_ system specific, and we need at
618 fprintf( stderr, "Getstack: %u\n", (unsigned int)n ); } 634 // least OS specific settings. Hopefully, Linuxes and OS X versions
619 // 524288 on OS X 635 // are uniform enough, among each other...
620 // 2097152 on Linux x86 (Ubuntu 7.04) 636 //
621 // 1048576 on FreeBSD 6.2 SMP i386 637# if defined PLATFORM_OSX
622#endif 638 // AK 10-Apr-07 (OS X PowerPC 10.4.9):
639 //
640 // With SCHED_RR, 26 seems to be the "normal" priority, where setting
641 // it does not seem to affect the order of threads processed.
642 //
643 // With SCHED_OTHER, the range 25..32 is normal (maybe the same 26,
644 // but the difference is not so clear with OTHER).
645 //
646 // 'sched_get_priority_min()' and '..max()' give 15, 47 as the
647 // priority limits. This could imply, user mode applications won't
648 // be able to use values outside of that range.
649 //
650# define _PRIO_MODE SCHED_OTHER
651
652 // OS X 10.4.9 (PowerPC) gives ENOTSUP for process scope
653 //#define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS
654
655# define _PRIO_HI 32 // seems to work (_carefully_ picked!)
656# define _PRIO_0 26 // detected
657# define _PRIO_LO 1 // seems to work (tested)
658
659# elif defined PLATFORM_LINUX
660 // (based on Ubuntu Linux 2.6.15 kernel)
661 //
662 // SCHED_OTHER is the default policy, but does not allow for priorities.
663 // SCHED_RR allows priorities, all of which (1..99) are higher than
664 // a thread with SCHED_OTHER policy.
665 //
666 // <http://kerneltrap.org/node/6080>
667 // <http://en.wikipedia.org/wiki/Native_POSIX_Thread_Library>
668 // <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html>
669 //
670 // Manuals suggest checking #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING,
671 // but even Ubuntu does not seem to define it.
672 //
673# define _PRIO_MODE SCHED_RR
623 674
624#if (defined _THREAD_STACK_SIZE) && (_THREAD_STACK_SIZE > 0) 675 // NTLP 2.5: only system scope allowed (being the basic reason why
625 PT_CALL( pthread_attr_setstacksize( a, _THREAD_STACK_SIZE ) ); 676 // root privileges are required..)
626#endif 677 //#define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS
627
628 normal=
629#if defined(PLATFORM_LINUX) && defined(LINUX_SCHED_RR)
630 !sudo; // with sudo, even normal thread must use SCHED_RR
631#else
632 prio == 0; // create a default thread if
633#endif
634 if (!normal) {
635 // NB: PThreads priority handling is about as twisty as one can get it
636 // (and then some). DON*T TRUST ANYTHING YOU READ ON THE NET!!!
637 678
638 // "The specified scheduling parameters are only used if the scheduling 679# define _PRIO_HI 99
639 // parameter inheritance attribute is PTHREAD_EXPLICIT_SCHED." 680# define _PRIO_0 50
640 // 681# define _PRIO_LO 1
641 PT_CALL( pthread_attr_setinheritsched( a, PTHREAD_EXPLICIT_SCHED ) );
642 682
643 //--- 683# elif defined(PLATFORM_BSD)
644 // "Select the scheduling policy for the thread: one of SCHED_OTHER 684 //
645 // (regular, non-real-time scheduling), SCHED_RR (real-time, 685 // <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html>
646 // round-robin) or SCHED_FIFO (real-time, first-in first-out)." 686 //
647 // 687 // "When control over the thread scheduling is desired, then FreeBSD
648 // "Using the RR policy ensures that all threads having the same 688 // with the libpthread implementation is by far the best choice .."
649 // priority level will be scheduled equally, regardless of their activity." 689 //
650 // 690# define _PRIO_MODE SCHED_OTHER
651 // "For SCHED_FIFO and SCHED_RR, the only required member of the 691# define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS
652 // sched_param structure is the priority sched_priority. For SCHED_OTHER, 692# define _PRIO_HI 31
653 // the affected scheduling parameters are implementation-defined." 693# define _PRIO_0 15
654 // 694# define _PRIO_LO 1
655 // "The priority of a thread is specified as a delta which is added to
656 // the priority of the process."
657 //
658 // ".. priority is an integer value, in the range from 1 to 127.
659 // 1 is the least-favored priority, 127 is the most-favored."
660 //
661 // "Priority level 0 cannot be used: it is reserved for the system."
662 //
663 // "When you use specify a priority of -99 in a call to
664 // pthread_setschedparam(), the priority of the target thread is
665 // lowered to the lowest possible value."
666 //
667 // ...
668 695
669 // ** CONCLUSION ** 696# elif defined(PLATFORM_CYGWIN)
670 // 697 //
671 // PThread priorities are _hugely_ system specific, and we need at 698 // TBD: Find right values for Cygwin
672 // least OS specific settings. Hopefully, Linuxes and OS X versions 699 //
673 // are uniform enough, among each other... 700# elif defined( PLATFORM_WIN32) || defined( PLATFORM_POCKETPC)
674 // 701 // any other value not supported by win32-pthread as of version 2.9.1
675#ifdef PLATFORM_OSX 702# define _PRIO_MODE SCHED_OTHER
676 // AK 10-Apr-07 (OS X PowerPC 10.4.9):
677 //
678 // With SCHED_RR, 26 seems to be the "normal" priority, where setting
679 // it does not seem to affect the order of threads processed.
680 //
681 // With SCHED_OTHER, the range 25..32 is normal (maybe the same 26,
682 // but the difference is not so clear with OTHER).
683 //
684 // 'sched_get_priority_min()' and '..max()' give 15, 47 as the
685 // priority limits. This could imply, user mode applications won't
686 // be able to use values outside of that range.
687 //
688 #define _PRIO_MODE SCHED_OTHER
689
690 // OS X 10.4.9 (PowerPC) gives ENOTSUP for process scope
691 //#define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS
692 703
693 #define _PRIO_HI 32 // seems to work (_carefully_ picked!) 704 // PTHREAD_SCOPE_PROCESS not supported by win32-pthread as of version 2.9.1
694 #define _PRIO_0 26 // detected 705 //#define _PRIO_SCOPE PTHREAD_SCOPE_SYSTEM // but do we need this at all to start with?
695 #define _PRIO_LO 1 // seems to work (tested) 706 THREAD_PRIORITY_IDLE, THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_BELOW_NORMAL, THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_ABOVE_NORMAL, THREAD_PRIORITY_HIGHEST, THREAD_PRIORITY_TIME_CRITICAL
696 707
697#elif defined(PLATFORM_LINUX) 708# else
698 // (based on Ubuntu Linux 2.6.15 kernel) 709# error "Unknown OS: not implemented!"
699 // 710# endif
700 // SCHED_OTHER is the default policy, but does not allow for priorities.
701 // SCHED_RR allows priorities, all of which (1..99) are higher than
702 // a thread with SCHED_OTHER policy.
703 //
704 // <http://kerneltrap.org/node/6080>
705 // <http://en.wikipedia.org/wiki/Native_POSIX_Thread_Library>
706 // <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html>
707 //
708 // Manuals suggest checking #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING,
709 // but even Ubuntu does not seem to define it.
710 //
711 #define _PRIO_MODE SCHED_RR
712
713 // NTLP 2.5: only system scope allowed (being the basic reason why
714 // root privileges are required..)
715 //#define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS
716 711
717 #define _PRIO_HI 99 712#if defined _PRIO_0
718 #define _PRIO_0 50 713# define _PRIO_AN (_PRIO_0 + ((_PRIO_HI-_PRIO_0)/2) )
719 #define _PRIO_LO 1 714# define _PRIO_BN (_PRIO_LO + ((_PRIO_0-_PRIO_LO)/2) )
720 715
721#elif defined(PLATFORM_BSD) 716 _PRIO_LO, _PRIO_LO, _PRIO_BN, _PRIO_0, _PRIO_AN, _PRIO_HI, _PRIO_HI
722 // 717#endif // _PRIO_0
723 // <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html> 718};
724 //
725 // "When control over the thread scheduling is desired, then FreeBSD
726 // with the libpthread implementation is by far the best choice .."
727 //
728 #define _PRIO_MODE SCHED_OTHER
729 #define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS
730 #define _PRIO_HI 31
731 #define _PRIO_0 15
732 #define _PRIO_LO 1
733 719
734#elif defined(PLATFORM_CYGWIN) 720//
735 // 721void THREAD_CREATE( THREAD_T* ref, THREAD_RETURN_T (*func)( void * ), void *data, int prio /* -2..+2 */)
736 // TBD: Find right values for Cygwin 722{
737 // 723 pthread_attr_t a;
738#elif defined( PLATFORM_WIN32) || defined( PLATFORM_POCKETPC) 724 bool_t const normal =
739 // any other value not supported by win32-pthread as of version 2.9.1 725#if defined(PLATFORM_LINUX) && defined(LINUX_SCHED_RR)
740 #define _PRIO_MODE SCHED_OTHER 726 !sudo; // with sudo, even normal thread must use SCHED_RR
741
742 // PTHREAD_SCOPE_PROCESS not supported by win32-pthread as of version 2.9.1
743 //#define _PRIO_SCOPE PTHREAD_SCOPE_SYSTEM // but do we need this at all to start with?
744
745#if defined __WINPTHREADS_VERSION
746 // see http://sourceforge.net/p/mingw-w64/code/6370/tree/trunk/mingw-w64-libraries/winpthreads/src/sched.c#l128
747 #define _PRIO_HI (+15)
748 #define _PRIO_0 (0)
749 #define _PRIO_LO (-15)
750#else
751 // win32-pthread seems happy with direct -2..+2 instead of some other remapping
752 #define _PRIO_HI (+2)
753 #define _PRIO_0 (0)
754 #define _PRIO_LO (-2)
755#endif
756#else 727#else
757 #error "Unknown OS: not implemented!" 728 (prio == 0);
758#endif 729#endif
759 730
760#ifdef _PRIO_SCOPE 731 PT_CALL( pthread_attr_init( &a));
761 PT_CALL( pthread_attr_setscope( a, _PRIO_SCOPE ) );
762#endif
763 PT_CALL( pthread_attr_setschedpolicy( a, _PRIO_MODE ) );
764 732
765#define _PRIO_AN (_PRIO_0 + ((_PRIO_HI-_PRIO_0)/2) ) 733#ifndef PTHREAD_TIMEDJOIN
766#define _PRIO_BN (_PRIO_LO + ((_PRIO_0-_PRIO_LO)/2) ) 734 // We create a NON-JOINABLE thread. This is mainly due to the lack of
735 // 'pthread_timedjoin()', but does offer other benefits (s.a. earlier
736 // freeing of the thread's resources).
737 //
738 PT_CALL( pthread_attr_setdetachstate( &a, PTHREAD_CREATE_DETACHED));
739#endif // PTHREAD_TIMEDJOIN
767 740
768 sp.sched_priority= 741 // Use this to find a system's default stack size (DEBUG)
769 (prio == +2) ? _PRIO_HI : 742#if 0
770 (prio == +1) ? _PRIO_AN : 743 {
771#if defined(PLATFORM_LINUX) && defined(LINUX_SCHED_RR) 744 size_t n;
772 (prio == 0) ? _PRIO_0 : 745 pthread_attr_getstacksize( &a, &n);
746 fprintf( stderr, "Getstack: %u\n", (unsigned int)n);
747 }
748 // 524288 on OS X
749 // 2097152 on Linux x86 (Ubuntu 7.04)
750 // 1048576 on FreeBSD 6.2 SMP i386
751#endif // 0
752
753#if defined _THREAD_STACK_SIZE && _THREAD_STACK_SIZE > 0
754 PT_CALL( pthread_attr_setstacksize( &a, _THREAD_STACK_SIZE));
773#endif 755#endif
774 (prio == -1) ? _PRIO_BN : _PRIO_LO;
775 756
776 PT_CALL( pthread_attr_setschedparam( a, &sp ) ); 757 if( !normal)
777 } 758 {
759 struct sched_param sp;
760 // "The specified scheduling parameters are only used if the scheduling
761 // parameter inheritance attribute is PTHREAD_EXPLICIT_SCHED."
762 //
763 PT_CALL( pthread_attr_setinheritsched( &a, PTHREAD_EXPLICIT_SCHED));
778 764
779 //---
780 // Seems on OS X, _POSIX_THREAD_THREADS_MAX is some kind of system
781 // thread limit (not userland thread). Actual limit for us is way higher.
782 // PTHREAD_THREADS_MAX is not defined (even though man page refers to it!)
783 //
784# ifndef THREAD_CREATE_RETRIES_MAX
785 // Don't bother with retries; a failure is a failure
786 //
787 {
788 int rc= pthread_create( ref, a, func, data );
789 if (rc) _PT_FAIL( rc, "pthread_create()", __FILE__, __LINE__-1 );
790 }
791# else
792# error "This code deprecated"
793/*
794 // Wait slightly if thread creation has exchausted the system
795 //
796 { uint_t retries;
797 for( retries=0; retries<THREAD_CREATE_RETRIES_MAX; retries++ ) {
798
799 int rc= pthread_create( ref, a, func, data );
800 //
801 // OS X / Linux:
802 // EAGAIN: ".. lacked the necessary resources to create
803 // another thread, or the system-imposed limit on the
804 // total number of threads in a process
805 // [PTHREAD_THREADS_MAX] would be exceeded."
806 // EINVAL: attr is invalid
807 // Linux:
808 // EPERM: no rights for given parameters or scheduling (no sudo)
809 // ENOMEM: (known to fail with this code, too - not listed in man)
810
811 if (rc==0) break; // ok!
812
813 // In practise, exhaustion seems to be coming from memory, not a
814 // maximum number of threads. Keep tuning... ;)
815 //
816 if (rc==EAGAIN) {
817//fprintf( stderr, "Looping (retries=%d) ", retries ); // DEBUG
818 765
819 // Try again, later. 766#ifdef _PRIO_SCOPE
767 PT_CALL( pthread_attr_setscope( &a, _PRIO_SCOPE));
768#endif // _PRIO_SCOPE
820 769
821 Yield(); 770 PT_CALL( pthread_attr_setschedpolicy( &a, _PRIO_MODE));
822 } else { 771
823 _PT_FAIL( rc, "pthread_create()", __FILE__, __LINE__ ); 772 // prio range [-3,+3] was checked by the caller
824 } 773 sp.sched_priority = gs_prio_remap[ prio + 3];
825 } 774 PT_CALL( pthread_attr_setschedparam( &a, &sp));
826 } 775 }
827*/ 776
777 //---
778 // Seems on OS X, _POSIX_THREAD_THREADS_MAX is some kind of system
779 // thread limit (not userland thread). Actual limit for us is way higher.
780 // PTHREAD_THREADS_MAX is not defined (even though man page refers to it!)
781 //
782# ifndef THREAD_CREATE_RETRIES_MAX
783 // Don't bother with retries; a failure is a failure
784 //
785 {
786 int rc = pthread_create( ref, &a, func, data);
787 if( rc) _PT_FAIL( rc, "pthread_create()", __FILE__, __LINE__ - 1);
788 }
789# else
790# error "This code deprecated"
791 /*
792 // Wait slightly if thread creation has exchausted the system
793 //
794 { uint_t retries;
795 for( retries=0; retries<THREAD_CREATE_RETRIES_MAX; retries++ ) {
796
797 int rc= pthread_create( ref, &a, func, data );
798 //
799 // OS X / Linux:
800 // EAGAIN: ".. lacked the necessary resources to create
801 // another thread, or the system-imposed limit on the
802 // total number of threads in a process
803 // [PTHREAD_THREADS_MAX] would be exceeded."
804 // EINVAL: attr is invalid
805 // Linux:
806 // EPERM: no rights for given parameters or scheduling (no sudo)
807 // ENOMEM: (known to fail with this code, too - not listed in man)
808
809 if (rc==0) break; // ok!
810
811 // In practise, exhaustion seems to be coming from memory, not a
812 // maximum number of threads. Keep tuning... ;)
813 //
814 if (rc==EAGAIN) {
815 //fprintf( stderr, "Looping (retries=%d) ", retries ); // DEBUG
816
817 // Try again, later.
818
819 Yield();
820 } else {
821 _PT_FAIL( rc, "pthread_create()", __FILE__, __LINE__ );
822 }
823 }
824 }
825 */
828# endif 826# endif
829 827
830 if (a) { 828 PT_CALL( pthread_attr_destroy( &a));
831 PT_CALL( pthread_attr_destroy(a) ); 829}
832 } 830
833 }
834 //
835 /* 831 /*
836 * Wait for a thread to finish. 832 * Wait for a thread to finish.
837 * 833 *
diff --git a/src/threading.h b/src/threading.h
index 4b28ce8..768d61c 100644
--- a/src/threading.h
+++ b/src/threading.h
@@ -202,7 +202,7 @@ bool_t SIGNAL_WAIT( SIGNAL_T *ref, MUTEX_T *mu, time_d timeout );
202 * implementation. Others will use a condition variable. 202 * implementation. Others will use a condition variable.
203 */ 203 */
204#if defined __WINPTHREADS_VERSION 204#if defined __WINPTHREADS_VERSION
205#define USE_PTHREAD_TIMEDJOIN 205//#define USE_PTHREAD_TIMEDJOIN
206#endif // __WINPTHREADS_VERSION 206#endif // __WINPTHREADS_VERSION
207# ifdef USE_PTHREAD_TIMEDJOIN 207# ifdef USE_PTHREAD_TIMEDJOIN
208# ifdef PLATFORM_OSX 208# ifdef PLATFORM_OSX
@@ -221,19 +221,16 @@ bool_t SIGNAL_WAIT( SIGNAL_T *ref, MUTEX_T *mu, time_d timeout );
221 void *data, int prio /* -2..+2 */ ); 221 void *data, int prio /* -2..+2 */ );
222 222
223# if defined(PLATFORM_LINUX) 223# if defined(PLATFORM_LINUX)
224 volatile bool_t sudo; 224 extern volatile bool_t sudo;
225# ifdef LINUX_SCHED_RR 225# ifdef LINUX_SCHED_RR
226# define THREAD_PRIO_MIN (sudo ? -2 : 0) 226# define THREAD_PRIO_MIN (sudo ? -3 : 0)
227# else 227# else
228# define THREAD_PRIO_MIN (0) 228# define THREAD_PRIO_MIN (0)
229# endif 229# endif
230# define THREAD_PRIO_MAX (sudo ? +2 : 0) 230# define THREAD_PRIO_MAX (sudo ? +3 : 0)
231# elif defined __WINPTHREADS_VERSION 231# else
232# define THREAD_PRIO_MIN (-3) 232# define THREAD_PRIO_MIN (-3)
233# define THREAD_PRIO_MAX (+3) 233# define THREAD_PRIO_MAX (+3)
234# else
235# define THREAD_PRIO_MIN (-2)
236# define THREAD_PRIO_MAX (+2)
237# endif 234# endif
238 235
239#define THREAD_CLEANUP_PUSH( cb_, val_) pthread_cleanup_push( cb_, val_) 236#define THREAD_CLEANUP_PUSH( cb_, val_) pthread_cleanup_push( cb_, val_)