Don't change thread priority if it is default under Unix
Skip all the code dealing with the priority/scheduling parameters if the priority is just wxPRIORITY_DEFAULT anyhow, as it's unnecessary to do anything in this case and it can result in spurious errors. Also extract this code into a separate SetThreadPriority() function to make wxThreadInternal::Create() itself shorter and more clear. Closes #18195.
This commit is contained in:
@@ -96,6 +96,7 @@ All:
|
|||||||
- Make wxList and wxVector iterators conform to input iterator requirements.
|
- Make wxList and wxVector iterators conform to input iterator requirements.
|
||||||
- Fix MT-safety problem when reading and writing from wxSocket (jkubalik).
|
- Fix MT-safety problem when reading and writing from wxSocket (jkubalik).
|
||||||
- Fix build issues under HaikuOS (mill-j).
|
- Fix build issues under HaikuOS (mill-j).
|
||||||
|
- Avoid spurious errors on thread creation under NetBSD.
|
||||||
|
|
||||||
All (GUI):
|
All (GUI):
|
||||||
|
|
||||||
|
@@ -987,6 +987,74 @@ wxThreadInternal::~wxThreadInternal()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool SetThreadPriority(pthread_attr_t& attr, int prio)
|
||||||
|
{
|
||||||
|
if ( prio == wxPRIORITY_DEFAULT )
|
||||||
|
{
|
||||||
|
// Don't even try to do anything, there is no need for it and it could
|
||||||
|
// result in failures if we don't handle setting the priority correctly
|
||||||
|
// under the current platform, see e.g. #18195.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_THREAD_PRIORITY_FUNCTIONS
|
||||||
|
int policy;
|
||||||
|
if ( pthread_attr_getschedpolicy(&attr, &policy) != 0 )
|
||||||
|
{
|
||||||
|
wxLogError(_("Cannot retrieve thread scheduling policy."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __VMS__
|
||||||
|
/* the pthread.h contains too many spaces. This is a work-around */
|
||||||
|
# undef sched_get_priority_max
|
||||||
|
#undef sched_get_priority_min
|
||||||
|
#define sched_get_priority_max(_pol_) \
|
||||||
|
(_pol_ == SCHED_OTHER ? PRI_FG_MAX_NP : PRI_FIFO_MAX)
|
||||||
|
#define sched_get_priority_min(_pol_) \
|
||||||
|
(_pol_ == SCHED_OTHER ? PRI_FG_MIN_NP : PRI_FIFO_MIN)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int max_prio = sched_get_priority_max(policy),
|
||||||
|
min_prio = sched_get_priority_min(policy);
|
||||||
|
|
||||||
|
if ( min_prio == -1 || max_prio == -1 )
|
||||||
|
{
|
||||||
|
wxLogError(_("Cannot get priority range for scheduling policy %d."),
|
||||||
|
policy);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( max_prio == min_prio )
|
||||||
|
{
|
||||||
|
// notify the programmer that this doesn't work here
|
||||||
|
wxLogWarning(_("Thread priority setting is ignored."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sched_param sp;
|
||||||
|
if ( pthread_attr_getschedparam(&attr, &sp) != 0 )
|
||||||
|
{
|
||||||
|
wxFAIL_MSG(wxT("pthread_attr_getschedparam() failed"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
sp.sched_priority = min_prio + (prio*(max_prio - min_prio))/100;
|
||||||
|
|
||||||
|
if ( pthread_attr_setschedparam(&attr, &sp) != 0 )
|
||||||
|
{
|
||||||
|
wxFAIL_MSG(wxT("pthread_attr_setschedparam(priority) failed"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
#else // !HAVE_THREAD_PRIORITY_FUNCTIONS
|
||||||
|
wxUnusedVar(attr);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
#endif // HAVE_THREAD_PRIORITY_FUNCTIONS
|
||||||
|
}
|
||||||
|
|
||||||
wxThreadError wxThreadInternal::Create(wxThread *thread, unsigned int stackSize)
|
wxThreadError wxThreadInternal::Create(wxThread *thread, unsigned int stackSize)
|
||||||
{
|
{
|
||||||
if ( GetState() != STATE_NEW )
|
if ( GetState() != STATE_NEW )
|
||||||
@@ -1006,60 +1074,14 @@ wxThreadError wxThreadInternal::Create(wxThread *thread, unsigned int stackSize)
|
|||||||
wxUnusedVar(stackSize);
|
wxUnusedVar(stackSize);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_THREAD_PRIORITY_FUNCTIONS
|
if ( !SetThreadPriority(attr, GetPriority()) )
|
||||||
int policy;
|
|
||||||
if ( pthread_attr_getschedpolicy(&attr, &policy) != 0 )
|
|
||||||
{
|
{
|
||||||
wxLogError(_("Cannot retrieve thread scheduling policy."));
|
// We currently ignore the failure to set the thread priority as it
|
||||||
|
// seems better to create a thread with default priority than to
|
||||||
|
// not create one at all.
|
||||||
|
wxLogDebug("Failed to set thread priority to %d", GetPriority());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __VMS__
|
|
||||||
/* the pthread.h contains too many spaces. This is a work-around */
|
|
||||||
# undef sched_get_priority_max
|
|
||||||
#undef sched_get_priority_min
|
|
||||||
#define sched_get_priority_max(_pol_) \
|
|
||||||
(_pol_ == SCHED_OTHER ? PRI_FG_MAX_NP : PRI_FIFO_MAX)
|
|
||||||
#define sched_get_priority_min(_pol_) \
|
|
||||||
(_pol_ == SCHED_OTHER ? PRI_FG_MIN_NP : PRI_FIFO_MIN)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int max_prio = sched_get_priority_max(policy),
|
|
||||||
min_prio = sched_get_priority_min(policy),
|
|
||||||
prio = GetPriority();
|
|
||||||
|
|
||||||
if ( min_prio == -1 || max_prio == -1 )
|
|
||||||
{
|
|
||||||
wxLogError(_("Cannot get priority range for scheduling policy %d."),
|
|
||||||
policy);
|
|
||||||
}
|
|
||||||
else if ( max_prio == min_prio )
|
|
||||||
{
|
|
||||||
if ( prio != wxPRIORITY_DEFAULT )
|
|
||||||
{
|
|
||||||
// notify the programmer that this doesn't work here
|
|
||||||
wxLogWarning(_("Thread priority setting is ignored."));
|
|
||||||
}
|
|
||||||
//else: we have default priority, so don't complain
|
|
||||||
|
|
||||||
// anyhow, don't do anything because priority is just ignored
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct sched_param sp;
|
|
||||||
if ( pthread_attr_getschedparam(&attr, &sp) != 0 )
|
|
||||||
{
|
|
||||||
wxFAIL_MSG(wxT("pthread_attr_getschedparam() failed"));
|
|
||||||
}
|
|
||||||
|
|
||||||
sp.sched_priority = min_prio + (prio*(max_prio - min_prio))/100;
|
|
||||||
|
|
||||||
if ( pthread_attr_setschedparam(&attr, &sp) != 0 )
|
|
||||||
{
|
|
||||||
wxFAIL_MSG(wxT("pthread_attr_setschedparam(priority) failed"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // HAVE_THREAD_PRIORITY_FUNCTIONS
|
|
||||||
|
|
||||||
#ifdef HAVE_PTHREAD_ATTR_SETSCOPE
|
#ifdef HAVE_PTHREAD_ATTR_SETSCOPE
|
||||||
// this will make the threads created by this process really concurrent
|
// this will make the threads created by this process really concurrent
|
||||||
if ( pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM) != 0 )
|
if ( pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM) != 0 )
|
||||||
|
Reference in New Issue
Block a user