aboutsummaryrefslogtreecommitdiff
path: root/src/threading.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/threading.c137
1 files changed, 73 insertions, 64 deletions
diff --git a/src/threading.c b/src/threading.c
index 183dc87..2b68503 100644
--- a/src/threading.c
+++ b/src/threading.c
@@ -323,9 +323,12 @@ void THREAD_CREATE( THREAD_T* ref, THREAD_RETURN_T (__stdcall *func)( void*), vo
323 FAIL( "CreateThread", GetLastError()); 323 FAIL( "CreateThread", GetLastError());
324 } 324 }
325 325
326 if (!SetThreadPriority( h, gs_prio_remap[prio + 3])) 326 if (prio != THREAD_PRIO_DEFAULT)
327 { 327 {
328 FAIL( "SetThreadPriority", GetLastError()); 328 if (!SetThreadPriority( h, gs_prio_remap[prio + 3]))
329 {
330 FAIL( "SetThreadPriority", GetLastError());
331 }
329 } 332 }
330 333
331 *ref = h; 334 *ref = h;
@@ -681,7 +684,7 @@ static int const gs_prio_remap[] =
681 // least OS specific settings. Hopefully, Linuxes and OS X versions 684 // least OS specific settings. Hopefully, Linuxes and OS X versions
682 // are uniform enough, among each other... 685 // are uniform enough, among each other...
683 // 686 //
684# if defined PLATFORM_OSX 687# if defined PLATFORM_OSX
685 // AK 10-Apr-07 (OS X PowerPC 10.4.9): 688 // AK 10-Apr-07 (OS X PowerPC 10.4.9):
686 // 689 //
687 // With SCHED_RR, 26 seems to be the "normal" priority, where setting 690 // With SCHED_RR, 26 seems to be the "normal" priority, where setting
@@ -694,85 +697,92 @@ static int const gs_prio_remap[] =
694 // priority limits. This could imply, user mode applications won't 697 // priority limits. This could imply, user mode applications won't
695 // be able to use values outside of that range. 698 // be able to use values outside of that range.
696 // 699 //
697# define _PRIO_MODE SCHED_OTHER 700# define _PRIO_MODE SCHED_OTHER
698 701
699 // OS X 10.4.9 (PowerPC) gives ENOTSUP for process scope 702 // OS X 10.4.9 (PowerPC) gives ENOTSUP for process scope
700 //#define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS 703 //#define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS
701 704
702# define _PRIO_HI 32 // seems to work (_carefully_ picked!) 705# define _PRIO_HI 32 // seems to work (_carefully_ picked!)
703# define _PRIO_0 26 // detected 706# define _PRIO_0 26 // detected
704# define _PRIO_LO 1 // seems to work (tested) 707# define _PRIO_LO 1 // seems to work (tested)
705 708
706# elif defined PLATFORM_LINUX 709# elif defined PLATFORM_LINUX
707 // (based on Ubuntu Linux 2.6.15 kernel) 710 // (based on Ubuntu Linux 2.6.15 kernel)
708 // 711 //
709 // SCHED_OTHER is the default policy, but does not allow for priorities. 712 // SCHED_OTHER is the default policy, but does not allow for priorities.
710 // SCHED_RR allows priorities, all of which (1..99) are higher than 713 // SCHED_RR allows priorities, all of which (1..99) are higher than
711 // a thread with SCHED_OTHER policy. 714 // a thread with SCHED_OTHER policy.
712 // 715 //
713 // <http://kerneltrap.org/node/6080> 716 // <http://kerneltrap.org/node/6080>
714 // <http://en.wikipedia.org/wiki/Native_POSIX_Thread_Library> 717 // <http://en.wikipedia.org/wiki/Native_POSIX_Thread_Library>
715 // <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html> 718 // <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html>
716 // 719 //
717 // Manuals suggest checking #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING, 720 // Manuals suggest checking #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING,
718 // but even Ubuntu does not seem to define it. 721 // but even Ubuntu does not seem to define it.
719 // 722 //
720# define _PRIO_MODE SCHED_RR 723# define _PRIO_MODE SCHED_RR
721 724
722 // NTLP 2.5: only system scope allowed (being the basic reason why 725 // NTLP 2.5: only system scope allowed (being the basic reason why
723 // root privileges are required..) 726 // root privileges are required..)
724 //#define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS 727 //#define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS
725 728
726# define _PRIO_HI 99 729# define _PRIO_HI 99
727# define _PRIO_0 50 730# define _PRIO_0 50
728# define _PRIO_LO 1 731# define _PRIO_LO 1
729 732
730# elif defined(PLATFORM_BSD) 733# elif defined(PLATFORM_BSD)
731 // 734 //
732 // <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html> 735 // <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html>
733 // 736 //
734 // "When control over the thread scheduling is desired, then FreeBSD 737 // "When control over the thread scheduling is desired, then FreeBSD
735 // with the libpthread implementation is by far the best choice .." 738 // with the libpthread implementation is by far the best choice .."
736 // 739 //
737# define _PRIO_MODE SCHED_OTHER 740# define _PRIO_MODE SCHED_OTHER
738# define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS 741# define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS
739# define _PRIO_HI 31 742# define _PRIO_HI 31
740# define _PRIO_0 15 743# define _PRIO_0 15
741# define _PRIO_LO 1 744# define _PRIO_LO 1
742 745
743# elif defined(PLATFORM_CYGWIN) 746# elif defined(PLATFORM_CYGWIN)
744 // 747 //
745 // TBD: Find right values for Cygwin 748 // TBD: Find right values for Cygwin
746 // 749 //
747# elif defined( PLATFORM_WIN32) || defined( PLATFORM_POCKETPC) 750# elif defined( PLATFORM_WIN32) || defined( PLATFORM_POCKETPC)
748 // any other value not supported by win32-pthread as of version 2.9.1 751 // any other value not supported by win32-pthread as of version 2.9.1
749# define _PRIO_MODE SCHED_OTHER 752# define _PRIO_MODE SCHED_OTHER
750 753
751 // PTHREAD_SCOPE_PROCESS not supported by win32-pthread as of version 2.9.1 754 // PTHREAD_SCOPE_PROCESS not supported by win32-pthread as of version 2.9.1
752 //#define _PRIO_SCOPE PTHREAD_SCOPE_SYSTEM // but do we need this at all to start with? 755 //#define _PRIO_SCOPE PTHREAD_SCOPE_SYSTEM // but do we need this at all to start with?
753 THREAD_PRIORITY_IDLE, THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_BELOW_NORMAL, THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_ABOVE_NORMAL, THREAD_PRIORITY_HIGHEST, THREAD_PRIORITY_TIME_CRITICAL 756 THREAD_PRIORITY_IDLE, THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_BELOW_NORMAL, THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_ABOVE_NORMAL, THREAD_PRIORITY_HIGHEST, THREAD_PRIORITY_TIME_CRITICAL
754 757
755# else 758# else
756# error "Unknown OS: not implemented!" 759# error "Unknown OS: not implemented!"
757# endif 760# endif
758 761
759#if defined _PRIO_0 762#if defined _PRIO_0
760# define _PRIO_AN (_PRIO_0 + ((_PRIO_HI-_PRIO_0)/2)) 763# define _PRIO_AN (_PRIO_0 + ((_PRIO_HI-_PRIO_0)/2))
761# define _PRIO_BN (_PRIO_LO + ((_PRIO_0-_PRIO_LO)/2)) 764# define _PRIO_BN (_PRIO_LO + ((_PRIO_0-_PRIO_LO)/2))
762 765
763 _PRIO_LO, _PRIO_LO, _PRIO_BN, _PRIO_0, _PRIO_AN, _PRIO_HI, _PRIO_HI 766 _PRIO_LO, _PRIO_LO, _PRIO_BN, _PRIO_0, _PRIO_AN, _PRIO_HI, _PRIO_HI
764#endif // _PRIO_0 767#endif // _PRIO_0
765}; 768};
766 769
770static int select_prio(int prio /* -3..+3 */)
771{
772 if (prio == THREAD_PRIO_DEFAULT)
773 prio = 0;
774 // prio range [-3,+3] was checked by the caller
775 return gs_prio_remap[prio + 3];
776}
777
767void THREAD_CREATE( THREAD_T* ref, THREAD_RETURN_T (*func)( void*), void* data, int prio /* -3..+3 */) 778void THREAD_CREATE( THREAD_T* ref, THREAD_RETURN_T (*func)( void*), void* data, int prio /* -3..+3 */)
768{ 779{
769 pthread_attr_t a; 780 pthread_attr_t a;
770 bool_t const normal = 781 bool_t const change_priority =
771#if defined(PLATFORM_LINUX) && defined(LINUX_SCHED_RR) 782#if defined(PLATFORM_LINUX) && defined(LINUX_SCHED_RR)
772 !sudo; // with sudo, even normal thread must use SCHED_RR 783 sudo && // with sudo, even normal thread must use SCHED_RR
773#else
774 (prio == 0);
775#endif 784#endif
785 (prio != THREAD_PRIO_DEFAULT);
776 786
777 PT_CALL( pthread_attr_init( &a)); 787 PT_CALL( pthread_attr_init( &a));
778 788
@@ -800,7 +810,7 @@ void THREAD_CREATE( THREAD_T* ref, THREAD_RETURN_T (*func)( void*), void* data,
800 PT_CALL( pthread_attr_setstacksize( &a, _THREAD_STACK_SIZE)); 810 PT_CALL( pthread_attr_setstacksize( &a, _THREAD_STACK_SIZE));
801#endif 811#endif
802 812
803 if( !normal) 813 if (change_priority)
804 { 814 {
805 struct sched_param sp; 815 struct sched_param sp;
806 // "The specified scheduling parameters are only used if the scheduling 816 // "The specified scheduling parameters are only used if the scheduling
@@ -816,8 +826,7 @@ void THREAD_CREATE( THREAD_T* ref, THREAD_RETURN_T (*func)( void*), void* data,
816 826
817 PT_CALL( pthread_attr_setschedpolicy( &a, _PRIO_MODE)); 827 PT_CALL( pthread_attr_setschedpolicy( &a, _PRIO_MODE));
818 828
819 // prio range [-3,+3] was checked by the caller 829 sp.sched_priority = select_prio(prio);
820 sp.sched_priority = gs_prio_remap[ prio + 3];
821 PT_CALL( pthread_attr_setschedparam( &a, &sp)); 830 PT_CALL( pthread_attr_setschedparam( &a, &sp));
822 } 831 }
823 832