Correct wxThread::SetPriority() under Unix to hopefully work.
The old implementation was completely broken, the new should hopefully work if pthread_setschedparam() behaviour really corresponds to its documentation. Mapping of our priorities in 0..100 range to pthread 1..99 range remains ugly but this seems to be unavoidable, unfortunately. Closes #14985. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@76116 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -23,6 +23,7 @@ All:
|
|||||||
- Allow iterating over wxCmdLineParser arguments in order (Armel Asselin).
|
- Allow iterating over wxCmdLineParser arguments in order (Armel Asselin).
|
||||||
- Add wxScopedArray ctor taking the number of elements to allocate.
|
- Add wxScopedArray ctor taking the number of elements to allocate.
|
||||||
- Add wxDynamicLibrary::GetModuleFromAddress() (Luca Bacci).
|
- Add wxDynamicLibrary::GetModuleFromAddress() (Luca Bacci).
|
||||||
|
- Implement wxThread::SetPriority() for pthreads (Luca Bacci).
|
||||||
|
|
||||||
All (GUI):
|
All (GUI):
|
||||||
|
|
||||||
|
@@ -1364,36 +1364,67 @@ void wxThread::SetPriority(unsigned int prio)
|
|||||||
|
|
||||||
case STATE_RUNNING:
|
case STATE_RUNNING:
|
||||||
case STATE_PAUSED:
|
case STATE_PAUSED:
|
||||||
|
{
|
||||||
#ifdef HAVE_THREAD_PRIORITY_FUNCTIONS
|
#ifdef HAVE_THREAD_PRIORITY_FUNCTIONS
|
||||||
#if defined(__LINUX__)
|
// We map our priority values to pthreads scheduling params as
|
||||||
// On Linux, pthread_setschedparam with SCHED_OTHER does not allow
|
// follows:
|
||||||
// a priority other than 0. Instead, we use the BSD setpriority
|
// 0..20 to SCHED_IDLE
|
||||||
// which alllows us to set a 'nice' value between 20 to -20. Only
|
// 21..40 to SCHED_BATCH
|
||||||
// super user can set a value less than zero (more negative yields
|
// 41..60 to SCHED_OTHER
|
||||||
// higher priority). setpriority set the static priority of a
|
// 61..80 to SCHED_RR
|
||||||
// process, but this is OK since Linux is configured as a thread
|
// 81..100 to SCHED_FIFO
|
||||||
// per process.
|
//
|
||||||
//
|
// For the last two, we can also use the additional priority
|
||||||
// FIXME this is not true for 2.6!!
|
// parameter which must be in 1..99 range under Linux (TODO:
|
||||||
|
// what should be used for the other systems?).
|
||||||
|
struct sched_param sparam = { 0 };
|
||||||
|
|
||||||
// map wx priorites 0..100 to Unix priorities 20..-20
|
// The only scheduling policy guaranteed to be supported
|
||||||
if ( setpriority(PRIO_PROCESS, 0, -(2*(int)prio)/5 + 20) == -1 )
|
// everywhere is this one.
|
||||||
{
|
int policy = SCHED_OTHER;
|
||||||
wxLogError(_("Failed to set thread priority %d."), prio);
|
#ifdef SCHED_IDLE
|
||||||
}
|
if ( prio <= 20 )
|
||||||
#else // __LINUX__
|
policy = SCHED_IDLE;
|
||||||
{
|
#endif
|
||||||
struct sched_param sparam;
|
#ifdef SCHED_BATCH
|
||||||
sparam.sched_priority = prio;
|
if ( 20 < prio && prio <= 40 )
|
||||||
|
policy = SCHED_BATCH;
|
||||||
|
#endif
|
||||||
|
#ifdef SCHED_RR
|
||||||
|
if ( 60 < prio && prio <= 80 )
|
||||||
|
policy = SCHED_RR;
|
||||||
|
#endif
|
||||||
|
#ifdef SCHED_FIFO
|
||||||
|
if ( 80 < prio )
|
||||||
|
policy = SCHED_FIFO;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// This test is not redundant as it takes care of the systems
|
||||||
|
// where neither SCHED_RR nor SCHED_FIFO are defined.
|
||||||
|
if ( prio > 60 && policy != SCHED_OTHER )
|
||||||
|
{
|
||||||
|
// There is no good way to map our 20 possible priorities
|
||||||
|
// (61..80 or 81..100) to the 99 pthread priorities, so we
|
||||||
|
// do the best that we can and ensure that the extremes of
|
||||||
|
// our range are mapped to the pthread extremes and all the
|
||||||
|
// rest fall in between.
|
||||||
|
|
||||||
|
// This gets us to 1..96 range.
|
||||||
|
sparam.sched_priority = ((prio - 61) % 20)*5 + 1;
|
||||||
|
|
||||||
|
// And we artificially increase our highest priority to the
|
||||||
|
// highest pthread one.
|
||||||
|
if ( sparam.sched_priority == 96 )
|
||||||
|
sparam.sched_priority = 99;
|
||||||
|
}
|
||||||
|
|
||||||
if ( pthread_setschedparam(m_internal->GetId(),
|
if ( pthread_setschedparam(m_internal->GetId(),
|
||||||
SCHED_OTHER, &sparam) != 0 )
|
policy, &sparam) != 0 )
|
||||||
{
|
{
|
||||||
wxLogError(_("Failed to set thread priority %d."), prio);
|
wxLogError(_("Failed to set thread priority %d."), prio);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif // __LINUX__
|
|
||||||
#endif // HAVE_THREAD_PRIORITY_FUNCTIONS
|
#endif // HAVE_THREAD_PRIORITY_FUNCTIONS
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_EXITED:
|
case STATE_EXITED:
|
||||||
|
Reference in New Issue
Block a user