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:
parent
f4edf48ec8
commit
9a61ced717
@ -23,6 +23,7 @@ All:
|
||||
- Allow iterating over wxCmdLineParser arguments in order (Armel Asselin).
|
||||
- Add wxScopedArray ctor taking the number of elements to allocate.
|
||||
- Add wxDynamicLibrary::GetModuleFromAddress() (Luca Bacci).
|
||||
- Implement wxThread::SetPriority() for pthreads (Luca Bacci).
|
||||
|
||||
All (GUI):
|
||||
|
||||
|
@ -1364,36 +1364,67 @@ void wxThread::SetPriority(unsigned int prio)
|
||||
|
||||
case STATE_RUNNING:
|
||||
case STATE_PAUSED:
|
||||
{
|
||||
#ifdef HAVE_THREAD_PRIORITY_FUNCTIONS
|
||||
#if defined(__LINUX__)
|
||||
// On Linux, pthread_setschedparam with SCHED_OTHER does not allow
|
||||
// a priority other than 0. Instead, we use the BSD setpriority
|
||||
// which alllows us to set a 'nice' value between 20 to -20. Only
|
||||
// super user can set a value less than zero (more negative yields
|
||||
// higher priority). setpriority set the static priority of a
|
||||
// process, but this is OK since Linux is configured as a thread
|
||||
// per process.
|
||||
//
|
||||
// FIXME this is not true for 2.6!!
|
||||
// We map our priority values to pthreads scheduling params as
|
||||
// follows:
|
||||
// 0..20 to SCHED_IDLE
|
||||
// 21..40 to SCHED_BATCH
|
||||
// 41..60 to SCHED_OTHER
|
||||
// 61..80 to SCHED_RR
|
||||
// 81..100 to SCHED_FIFO
|
||||
//
|
||||
// For the last two, we can also use the additional priority
|
||||
// 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
|
||||
if ( setpriority(PRIO_PROCESS, 0, -(2*(int)prio)/5 + 20) == -1 )
|
||||
{
|
||||
wxLogError(_("Failed to set thread priority %d."), prio);
|
||||
}
|
||||
#else // __LINUX__
|
||||
{
|
||||
struct sched_param sparam;
|
||||
sparam.sched_priority = prio;
|
||||
// The only scheduling policy guaranteed to be supported
|
||||
// everywhere is this one.
|
||||
int policy = SCHED_OTHER;
|
||||
#ifdef SCHED_IDLE
|
||||
if ( prio <= 20 )
|
||||
policy = SCHED_IDLE;
|
||||
#endif
|
||||
#ifdef SCHED_BATCH
|
||||
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(),
|
||||
SCHED_OTHER, &sparam) != 0 )
|
||||
policy, &sparam) != 0 )
|
||||
{
|
||||
wxLogError(_("Failed to set thread priority %d."), prio);
|
||||
}
|
||||
}
|
||||
#endif // __LINUX__
|
||||
#endif // HAVE_THREAD_PRIORITY_FUNCTIONS
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_EXITED:
|
||||
|
Loading…
Reference in New Issue
Block a user