diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-03-22 18:38:54 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-03-22 18:38:54 (GMT) |
commit | 7857d88a0163d12aca51c017d3fe1878fc3b89ae (patch) | |
tree | 8ce1955e31b37579aa6df2803a2f2ddd5581e735 /src/corelib/thread/qthread_unix.cpp | |
parent | 58e9855afce71448c709469270950e5add87d601 (diff) | |
parent | 397a2680b4e7ce90a8e4f8a4617450adb5d5a37d (diff) | |
download | Qt-7857d88a0163d12aca51c017d3fe1878fc3b89ae.zip Qt-7857d88a0163d12aca51c017d3fe1878fc3b89ae.tar.gz Qt-7857d88a0163d12aca51c017d3fe1878fc3b89ae.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-1 into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-1: (92 commits)
Make QStackTextEngine cheaper to construct
Add a function to get the transitions available from a state
Add a new WA_X11DoNotAcceptFocus attribute for top-level widgets (part 2).
Code cleaning for the QStringList's joinEmptiness() test case
Fix behavior change QStringList::join() for null
Add a new WA_X11DoNotAcceptFocus attribute for top-level widgets.
Cocoa: fix eventdispatcher crash, found by macgui autotest
Make QWidget::activateWindow() NET window manager aware.
Upgraded QLocale data to Unicode CLDR 1.8.0
Improved CLDR parser.
Fixed reading draft data from CLDR.
Improved the cldr parser for QLocale.
Do not use FSEvents-based filesystemwatcher backend on Mac.
add file missing in commit 74f5e34979b8a08a91aa3c2fa6d252e68eca7817
Moc: Add support for rvalue references in signals and slots.
Add support for polyphonic greek
Fix build failure on WinCE.
Autotests: if you use X11 libs, you must link to X11 libs explicitly.
Disable C++0x mode for QtWebKit and QtScript since WebKit will not compile any time soon with C++0x
Compile Phonon in C++0x mode.
...
Diffstat (limited to 'src/corelib/thread/qthread_unix.cpp')
-rw-r--r-- | src/corelib/thread/qthread_unix.cpp | 107 |
1 files changed, 62 insertions, 45 deletions
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index cda35a4..5a50646 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -92,10 +92,17 @@ # endif #endif +#if defined(Q_OS_LINUX) && !defined(SCHED_IDLE) +// from linux/sched.h +# define SCHED_IDLE 5 +#endif + QT_BEGIN_NAMESPACE #ifndef QT_NO_THREAD +enum { ThreadPriorityResetFlag = 0x80000000 }; + static pthread_once_t current_thread_data_once = PTHREAD_ONCE_INIT; static pthread_key_t current_thread_data_key; @@ -221,6 +228,11 @@ void *QThreadPrivate::start(void *arg) QThread *thr = reinterpret_cast<QThread *>(arg); QThreadData *data = QThreadData::get2(thr); + // do we need to reset the thread priority? + if (int(thr->d_func()->priority) & ThreadPriorityResetFlag) { + thr->setPriority(QThread::Priority(thr->d_func()->priority & ~ThreadPriorityResetFlag)); + } + #ifdef Q_OS_SYMBIAN // Because Symbian Open C does not provide a way to convert between // RThread and pthread_t, we must delay initialization of the RThread @@ -436,6 +448,37 @@ void QThread::usleep(unsigned long usecs) thread_sleep(&ti); } +// Does some magic and calculate the Unix scheduler priorities +// sched_policy is IN/OUT: it must be set to a valid policy before calling this function +// sched_priority is OUT only +static bool calculateUnixPriority(int priority, int *sched_policy, int *sched_priority) +{ +#ifdef SCHED_IDLE + if (priority == QThread::IdlePriority) { + *sched_policy = SCHED_IDLE; + *sched_priority = 0; + return true; + } + const int lowestPriority = QThread::LowestPriority; +#else + const int lowestPriority = QThread::IdlePriority; +#endif + const int highestPriority = QThread::TimeCriticalPriority; + + int prio_min = sched_get_priority_min(*sched_policy); + int prio_max = sched_get_priority_max(*sched_policy); + if (prio_min == -1 || prio_max == -1) + return false; + + int prio; + // crudely scale our priority enum values to the prio_min/prio_max + prio = ((priority - lowestPriority) * (prio_max - prio_min) / highestPriority) + prio_min; + prio = qMax(prio_min, qMin(prio_max, prio)); + + *sched_priority = prio; + return true; +} + void QThread::start(Priority priority) { Q_D(QThread); @@ -472,32 +515,14 @@ void QThread::start(Priority priority) break; } - int prio_min = sched_get_priority_min(sched_policy); - int prio_max = sched_get_priority_max(sched_policy); - if (prio_min == -1 || prio_max == -1) { + int prio; + if (!calculateUnixPriority(priority, &sched_policy, &prio)) { // failed to get the scheduling parameters, don't // bother setting the priority qWarning("QThread::start: Cannot determine scheduler priority range"); break; } - int prio; - switch (priority) { - case IdlePriority: - prio = prio_min; - break; - - case TimeCriticalPriority: - prio = prio_max; - break; - - default: - // crudely scale our priority enum values to the prio_min/prio_max - prio = (priority * (prio_max - prio_min) / TimeCriticalPriority) + prio_min; - prio = qMax(prio_min, qMin(prio_max, prio)); - break; - } - sched_param sp; sp.sched_priority = prio; @@ -505,7 +530,9 @@ void QThread::start(Priority priority) || pthread_attr_setschedpolicy(&attr, sched_policy) != 0 || pthread_attr_setschedparam(&attr, &sp) != 0) { // could not set scheduling hints, fallback to inheriting them + // we'll try again from inside the thread pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); + d->priority = Priority(priority | ThreadPriorityResetFlag); } break; } @@ -672,38 +699,28 @@ void QThread::setPriority(Priority priority) return; } - int prio_min = sched_get_priority_min(sched_policy); - int prio_max = sched_get_priority_max(sched_policy); - if (prio_min == -1 || prio_max == -1) { + int prio; + if (!calculateUnixPriority(priority, &sched_policy, &prio)) { // failed to get the scheduling parameters, don't // bother setting the priority qWarning("QThread::setPriority: Cannot determine scheduler priority range"); return; } - int prio; - switch (priority) { - case InheritPriority: - qWarning("QThread::setPriority: Argument cannot be InheritPriority"); - return; - - case IdlePriority: - prio = prio_min; - break; - - case TimeCriticalPriority: - prio = prio_max; - break; - - default: - // crudely scale our priority enum values to the prio_min/prio_max - prio = (priority * (prio_max - prio_min) / TimeCriticalPriority) + prio_min; - prio = qMax(prio_min, qMin(prio_max, prio)); - break; - } - param.sched_priority = prio; - pthread_setschedparam(d->thread_id, sched_policy, ¶m); + int status = pthread_setschedparam(d->thread_id, sched_policy, ¶m); + +# ifdef SCHED_IDLE + // were we trying to set to idle priority and failed? + if (status == -1 && sched_policy == SCHED_IDLE && errno == EINVAL) { + // reset to lowest priority possible + pthread_getschedparam(d->thread_id, &sched_policy, ¶m); + param.sched_priority = sched_get_priority_min(sched_policy); + pthread_setschedparam(d->thread_id, sched_policy, ¶m); + } +# else + Q_UNUSED(status); +# endif // SCHED_IDLE #endif } |