diff options
Diffstat (limited to '')
-rw-r--r-- | src/threading.c | 137 |
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 | ||
770 | static 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 | |||
767 | void THREAD_CREATE( THREAD_T* ref, THREAD_RETURN_T (*func)( void*), void* data, int prio /* -3..+3 */) | 778 | void 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 | ||