Qt 4.8
qthread_unix.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qthread.h"
43 
44 #include "qplatformdefs.h"
45 
46 #include <private/qcoreapplication_p.h>
47 
48 #if defined(Q_OS_BLACKBERRY)
49 # include <private/qeventdispatcher_blackberry_p.h>
50 #else
51 # if !defined(QT_NO_GLIB)
52 # include "../kernel/qeventdispatcher_glib_p.h"
53 # endif
54 # include <private/qeventdispatcher_unix_p.h>
55 #endif
56 
57 #include "qthreadstorage.h"
58 
59 #include "qthread_p.h"
60 
61 #include "qdebug.h"
62 
63 #include <sched.h>
64 #include <errno.h>
65 
66 #ifdef Q_OS_BSD4
67 #include <sys/sysctl.h>
68 #endif
69 #ifdef Q_OS_VXWORKS
70 # if (_WRS_VXWORKS_MAJOR > 6) || ((_WRS_VXWORKS_MAJOR == 6) && (_WRS_VXWORKS_MINOR >= 6))
71 # include <vxCpuLib.h>
72 # include <cpuset.h>
73 # define QT_VXWORKS_HAS_CPUSET
74 # endif
75 #endif
76 
77 #ifdef Q_OS_HPUX
78 #include <sys/pstat.h>
79 #endif
80 
81 #if defined(Q_OS_MAC)
82 # ifdef qDebug
83 # define old_qDebug qDebug
84 # undef qDebug
85 # endif
86 #if !defined(Q_OS_IOS)
87 # include <CoreServices/CoreServices.h>
88 #endif // !defined(Q_OS_IOS)
89 
90 # ifdef old_qDebug
91 # undef qDebug
92 # define qDebug QT_NO_QDEBUG_MACRO
93 # undef old_qDebug
94 # endif
95 #endif
96 
97 #if defined(Q_OS_LINUX) && !defined(QT_LINUXBASE)
98 #include <sys/prctl.h>
99 #endif
100 
101 #if defined(Q_OS_LINUX) && !defined(SCHED_IDLE)
102 // from linux/sched.h
103 # define SCHED_IDLE 5
104 #endif
105 
106 #if defined(Q_OS_DARWIN) || !defined(Q_OS_OPENBSD) && defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING-0 >= 0)
107 #define QT_HAS_THREAD_PRIORITY_SCHEDULING
108 #endif
109 
110 
112 
113 #ifndef QT_NO_THREAD
114 
115 enum { ThreadPriorityResetFlag = 0x80000000 };
116 
117 #if defined(Q_OS_LINUX) && defined(__GLIBC__) && (defined(Q_CC_GNU) || defined(Q_CC_INTEL))
118 #define HAVE_TLS
119 #endif
120 #if defined(Q_CC_XLC) || defined (Q_CC_SUN)
121 #define HAVE_TLS
122 #endif
123 
124 #ifdef HAVE_TLS
125 static __thread QThreadData *currentThreadData = 0;
126 #endif
127 
128 static pthread_once_t current_thread_data_once = PTHREAD_ONCE_INIT;
129 static pthread_key_t current_thread_data_key;
130 
131 static void destroy_current_thread_data(void *p)
132 {
133 #if defined(Q_OS_VXWORKS)
134  // Calling setspecific(..., 0) sets the value to 0 for ALL threads.
135  // The 'set to 1' workaround adds a bit of an overhead though,
136  // since this function is called twice now.
137  if (p == (void *)1)
138  return;
139 #endif
140  // POSIX says the value in our key is set to zero before calling
141  // this destructor function, so we need to set it back to the
142  // right value...
143  pthread_setspecific(current_thread_data_key, p);
144  QThreadData *data = static_cast<QThreadData *>(p);
145  if (data->isAdopted) {
146  QThread *thread = data->thread;
147  Q_ASSERT(thread);
148  QThreadPrivate *thread_p = static_cast<QThreadPrivate *>(QObjectPrivate::get(thread));
149  Q_ASSERT(!thread_p->finished);
150  thread_p->finish(thread);
151  }
152  data->deref();
153 
154  // ... but we must reset it to zero before returning so we aren't
155  // called again (POSIX allows implementations to call destructor
156  // functions repeatedly until all values are zero)
157  pthread_setspecific(current_thread_data_key,
158 #if defined(Q_OS_VXWORKS)
159  (void *)1);
160 #else
161  0);
162 #endif
163 }
164 
166 {
168 }
169 
171 {
173  pthread_key_delete(current_thread_data_key);
174 
175  // Reset current_thread_data_once in case we end up recreating
176  // the thread-data in the rare case of QObject construction
177  // after destroying the QThreadData.
178  pthread_once_t pthread_once_init = PTHREAD_ONCE_INIT;
179  current_thread_data_once = pthread_once_init;
180 }
182 
183 
184 // Utility functions for getting, setting and clearing thread specific data.
186 {
187 #ifdef HAVE_TLS
188  return currentThreadData;
189 #else
191  return reinterpret_cast<QThreadData *>(pthread_getspecific(current_thread_data_key));
192 #endif
193 }
194 
196 {
197 #ifdef HAVE_TLS
198  currentThreadData = data;
199 #endif
201  pthread_setspecific(current_thread_data_key, data);
202 }
203 
204 static void clear_thread_data()
205 {
206 #ifdef HAVE_TLS
207  currentThreadData = 0;
208 #endif
209  pthread_setspecific(current_thread_data_key, 0);
210 }
211 
213 {
215 }
216 
218 {
220  if (!data) {
221  void *a;
223  QThread *adopted = static_cast<QThread*>(a);
224  Q_ASSERT(adopted);
225  data = QThreadData::get2(adopted);
226  set_thread_data(data);
227  adopted->d_func()->running = true;
228  adopted->d_func()->finished = false;
229  static_cast<QAdoptedThread *>(adopted)->init();
230  } else {
231  data = new QThreadData;
232  QT_TRY {
233  set_thread_data(data);
234  data->thread = new QAdoptedThread(data);
235  } QT_CATCH(...) {
237  data->deref();
238  data = 0;
239  QT_RETHROW;
240  }
241  data->deref();
242  }
243  data->isAdopted = true;
244  data->threadId = (Qt::HANDLE)pthread_self();
247  }
248  return data;
249 }
250 
251 
253 {
254  Q_D(QThread);
255  d->thread_id = pthread_self();
256 }
257 
258 /*
259  QThreadPrivate
260 */
261 
262 #if defined(Q_C_CALLBACKS)
263 extern "C" {
264 #endif
265 
266 typedef void*(*QtThreadCallback)(void*);
267 
268 #if defined(Q_C_CALLBACKS)
269 }
270 #endif
271 
272 #endif // QT_NO_THREAD
273 
275 {
276 #if defined(Q_OS_BLACKBERRY)
278 #else
279 #if !defined(QT_NO_GLIB)
280  if (qgetenv("QT_NO_GLIB").isEmpty()
281  && qgetenv("QT_NO_THREADED_GLIB").isEmpty()
284  else
285 #endif
287 #endif
288 
289  data->eventDispatcher->startingUp();
290 }
291 
292 #ifndef QT_NO_THREAD
293 
294 #if (defined(Q_OS_LINUX) || (defined(Q_OS_MAC) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) || defined(Q_OS_QNX))
295 static void setCurrentThreadName(pthread_t threadId, const char *name)
296 {
297 # if defined(Q_OS_LINUX) && !defined(QT_LINUXBASE)
298  Q_UNUSED(threadId);
299  prctl(PR_SET_NAME, (unsigned long)name, 0, 0, 0);
300 # elif (defined(Q_OS_MAC) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
301  Q_UNUSED(threadId);
303  pthread_setname_np(name);
304 # elif defined(Q_OS_QNX)
305  pthread_setname_np(threadId, name);
306 # endif
307 }
308 #endif
309 
310 void *QThreadPrivate::start(void *arg)
311 {
312  pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
314 
315  QThread *thr = reinterpret_cast<QThread *>(arg);
317 
318  // do we need to reset the thread priority?
319  if (int(thr->d_func()->priority) & ThreadPriorityResetFlag) {
321  }
322 
323  data->threadId = (Qt::HANDLE)pthread_self();
324  set_thread_data(data);
325 
326  data->ref();
327  {
328  QMutexLocker locker(&thr->d_func()->mutex);
329  data->quitNow = thr->d_func()->exited;
330  }
331 
332  // ### TODO: allow the user to create a custom event dispatcher
333  createEventDispatcher(data);
334 
335 #if (defined(Q_OS_LINUX) || (defined(Q_OS_MAC) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) || defined(Q_OS_QNX))
336  // sets the name of the current thread.
337  QString objectName = thr->objectName();
338 
339  if (Q_LIKELY(objectName.isEmpty()))
340  setCurrentThreadName(thr->d_func()->thread_id, thr->metaObject()->className());
341  else
342  setCurrentThreadName(thr->d_func()->thread_id, objectName.toLocal8Bit());
343 
344 #endif
345 
346  emit thr->started();
347  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
349  thr->run();
350 
352 
353  return 0;
354 }
355 
356 void QThreadPrivate::finish(void *arg)
357 {
358  QThread *thr = reinterpret_cast<QThread *>(arg);
359  QThreadPrivate *d = thr->d_func();
360 
361  QMutexLocker locker(&d->mutex);
362 
363  d->isInFinish = true;
365  bool terminated = d->terminated;
366  void *data = &d->data->tls;
367  locker.unlock();
368  if (terminated)
369  emit thr->terminated();
370  emit thr->finished();
372  QThreadStorageData::finish((void **)data);
373  locker.relock();
374  d->terminated = false;
375 
377  if (eventDispatcher) {
378  d->data->eventDispatcher = 0;
379  locker.unlock();
380  eventDispatcher->closingDown();
381  delete eventDispatcher;
382  locker.relock();
383  }
384 
385  d->thread_id = 0;
386  d->running = false;
387  d->finished = true;
388 
389  d->isInFinish = false;
390  d->thread_done.wakeAll();
391 }
392 
393 
394 
395 
396 /**************************************************************************
397  ** QThread
398  *************************************************************************/
399 
401 {
402  // requires a C cast here otherwise we run into trouble on AIX
403  return (Qt::HANDLE)pthread_self();
404 }
405 
406 #if defined(QT_LINUXBASE) && !defined(_SC_NPROCESSORS_ONLN)
407 // LSB doesn't define _SC_NPROCESSORS_ONLN.
408 # define _SC_NPROCESSORS_ONLN 84
409 #endif
410 
412 {
413  int cores = -1;
414 
415 #if defined(Q_OS_MAC) && !defined(Q_WS_QPA)
416  // Mac OS X
417  cores = MPProcessorsScheduled();
418 #elif defined(Q_OS_HPUX)
419  // HP-UX
420  struct pst_dynamic psd;
421  if (pstat_getdynamic(&psd, sizeof(psd), 1, 0) == -1) {
422  perror("pstat_getdynamic");
423  cores = -1;
424  } else {
425  cores = (int)psd.psd_proc_cnt;
426  }
427 #elif defined(Q_OS_BSD4)
428  // FreeBSD, OpenBSD, NetBSD, BSD/OS
429  size_t len = sizeof(cores);
430  int mib[2];
431  mib[0] = CTL_HW;
432  mib[1] = HW_NCPU;
433  if (sysctl(mib, 2, &cores, &len, NULL, 0) != 0) {
434  perror("sysctl");
435  cores = -1;
436  }
437 #elif defined(Q_OS_IRIX)
438  // IRIX
439  cores = (int)sysconf(_SC_NPROC_ONLN);
440 #elif defined(Q_OS_INTEGRITY)
441 #if (__INTEGRITY_MAJOR_VERSION >= 10)
442  // Integrity V10+ does support multicore CPUs
443  Value processorCount;
444  if (GetProcessorCount(CurrentTask(), &processorCount) == 0)
445  cores = processorCount;
446  else
447 #endif
448  cores = 1;
449 #elif defined(Q_OS_VXWORKS)
450  // VxWorks
451 # if defined(QT_VXWORKS_HAS_CPUSET)
452  cpuset_t cpus = vxCpuEnabledGet();
453  cores = 0;
454 
455  // 128 cores should be enough for everyone ;)
456  for (int i = 0; i < 128 && !CPUSET_ISZERO(cpus); ++i) {
457  if (CPUSET_ISSET(cpus, i)) {
458  CPUSET_CLR(cpus, i);
459  cores++;
460  }
461  }
462 # else
463  // as of aug 2008 VxWorks < 6.6 only supports one single core CPU
464  cores = 1;
465 # endif
466 #else
467  // the rest: Linux, Solaris, AIX, Tru64
468  cores = (int)sysconf(_SC_NPROCESSORS_ONLN);
469 #endif
470 
471  return cores;
472 }
473 
475 {
476  sched_yield();
477 }
478 
479 /* \internal
480  helper function to do thread sleeps, since usleep()/nanosleep()
481  aren't reliable enough (in terms of behavior and availability)
482 */
483 static void thread_sleep(struct timespec *ti)
484 {
485  pthread_mutex_t mtx;
486  pthread_cond_t cnd;
487 
488  pthread_mutex_init(&mtx, 0);
489  pthread_cond_init(&cnd, 0);
490 
491  pthread_mutex_lock(&mtx);
492  (void) pthread_cond_timedwait(&cnd, &mtx, ti);
493  pthread_mutex_unlock(&mtx);
494 
495  pthread_cond_destroy(&cnd);
496  pthread_mutex_destroy(&mtx);
497 }
498 
499 void QThread::sleep(unsigned long secs)
500 {
501  struct timeval tv;
502  gettimeofday(&tv, 0);
503  struct timespec ti;
504  ti.tv_sec = tv.tv_sec + secs;
505  ti.tv_nsec = (tv.tv_usec * 1000);
506  thread_sleep(&ti);
507 }
508 
509 void QThread::msleep(unsigned long msecs)
510 {
511  struct timeval tv;
512  gettimeofday(&tv, 0);
513  struct timespec ti;
514 
515  ti.tv_nsec = (tv.tv_usec + (msecs % 1000) * 1000) * 1000;
516  ti.tv_sec = tv.tv_sec + (msecs / 1000) + (ti.tv_nsec / 1000000000);
517  ti.tv_nsec %= 1000000000;
518  thread_sleep(&ti);
519 }
520 
521 void QThread::usleep(unsigned long usecs)
522 {
523  struct timeval tv;
524  gettimeofday(&tv, 0);
525  struct timespec ti;
526 
527  ti.tv_nsec = (tv.tv_usec + (usecs % 1000000)) * 1000;
528  ti.tv_sec = tv.tv_sec + (usecs / 1000000) + (ti.tv_nsec / 1000000000);
529  ti.tv_nsec %= 1000000000;
530  thread_sleep(&ti);
531 }
532 
533 #ifdef QT_HAS_THREAD_PRIORITY_SCHEDULING
534 // Does some magic and calculate the Unix scheduler priorities
535 // sched_policy is IN/OUT: it must be set to a valid policy before calling this function
536 // sched_priority is OUT only
537 static bool calculateUnixPriority(int priority, int *sched_policy, int *sched_priority)
538 {
539 #ifdef Q_OS_QNX
540  // without Round Robin drawn intensive apps will hog the cpu
541  // and make the system appear frozen
542  *sched_policy = SCHED_RR;
543 #endif
544 #ifdef SCHED_IDLE
545  if (priority == QThread::IdlePriority) {
546  *sched_policy = SCHED_IDLE;
547  *sched_priority = 0;
548  return true;
549  }
550  const int lowestPriority = QThread::LowestPriority;
551 #else
552  const int lowestPriority = QThread::IdlePriority;
553 #endif
554  const int highestPriority = QThread::TimeCriticalPriority;
555 
556  int prio_min;
557  int prio_max;
558 #if defined(Q_OS_VXWORKS) && defined(VXWORKS_DKM)
559  // for other scheduling policies than SCHED_RR or SCHED_FIFO
560  prio_min = SCHED_FIFO_LOW_PRI;
561  prio_max = SCHED_FIFO_HIGH_PRI;
562 
563  if ((*sched_policy == SCHED_RR) || (*sched_policy == SCHED_FIFO))
564 #endif
565  {
566  prio_min = sched_get_priority_min(*sched_policy);
567  prio_max = sched_get_priority_max(*sched_policy);
568  }
569 
570  if (prio_min == -1 || prio_max == -1)
571  return false;
572 
573  int prio;
574  // crudely scale our priority enum values to the prio_min/prio_max
575  prio = ((priority - lowestPriority) * (prio_max - prio_min) / highestPriority) + prio_min;
576  prio = qMax(prio_min, qMin(prio_max, prio));
577 
578  *sched_priority = prio;
579  return true;
580 }
581 #endif
582 
583 void QThread::start(Priority priority)
584 {
585  Q_D(QThread);
586  QMutexLocker locker(&d->mutex);
587 
588  if (d->isInFinish)
589  d->thread_done.wait(locker.mutex());
590 
591  if (d->running)
592  return;
593 
594  d->running = true;
595  d->finished = false;
596  d->terminated = false;
597  d->returnCode = 0;
598  d->exited = false;
599 
600  pthread_attr_t attr;
601  pthread_attr_init(&attr);
602  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
603 
604  d->priority = priority;
605 
606 #if defined(QT_HAS_THREAD_PRIORITY_SCHEDULING)
607  switch (priority) {
608  case InheritPriority:
609  {
610  pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
611  break;
612  }
613 
614  default:
615  {
616  int sched_policy;
617  if (pthread_attr_getschedpolicy(&attr, &sched_policy) != 0) {
618  // failed to get the scheduling policy, don't bother
619  // setting the priority
620  qWarning("QThread::start: Cannot determine default scheduler policy");
621  break;
622  }
623 
624  int prio;
625  if (!calculateUnixPriority(priority, &sched_policy, &prio)) {
626  // failed to get the scheduling parameters, don't
627  // bother setting the priority
628  qWarning("QThread::start: Cannot determine scheduler priority range");
629  break;
630  }
631 
632  sched_param sp;
633  sp.sched_priority = prio;
634 
635  if (pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) != 0
636  || pthread_attr_setschedpolicy(&attr, sched_policy) != 0
637  || pthread_attr_setschedparam(&attr, &sp) != 0) {
638  // could not set scheduling hints, fallback to inheriting them
639  // we'll try again from inside the thread
640  pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
641  d->priority = Priority(priority | ThreadPriorityResetFlag);
642  }
643  break;
644  }
645  }
646 #endif // QT_HAS_THREAD_PRIORITY_SCHEDULING
647 
648 
649  if (d->stackSize > 0) {
650 #if defined(_POSIX_THREAD_ATTR_STACKSIZE) && (_POSIX_THREAD_ATTR_STACKSIZE-0 > 0)
651  int code = pthread_attr_setstacksize(&attr, d->stackSize);
652 #else
653  int code = ENOSYS; // stack size not supported, automatically fail
654 #endif // _POSIX_THREAD_ATTR_STACKSIZE
655 
656  if (code) {
657  qWarning("QThread::start: Thread stack size error: %s",
658  qPrintable(qt_error_string(code)));
659 
660  // we failed to set the stacksize, and as the documentation states,
661  // the thread will fail to run...
662  d->running = false;
663  d->finished = false;
664  return;
665  }
666  }
667 
668  int code =
669  pthread_create(&d->thread_id, &attr, QThreadPrivate::start, this);
670  if (code == EPERM) {
671  // caller does not have permission to set the scheduling
672  // parameters/policy
673  pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
674  code =
675  pthread_create(&d->thread_id, &attr, QThreadPrivate::start, this);
676  }
677 
678  pthread_attr_destroy(&attr);
679 
680  if (code) {
681  qWarning("QThread::start: Thread creation error: %s", qPrintable(qt_error_string(code)));
682 
683  d->running = false;
684  d->finished = false;
685  d->thread_id = 0;
686  }
687 }
688 
690 {
691  Q_D(QThread);
692  QMutexLocker locker(&d->mutex);
693 
694  if (!d->thread_id)
695  return;
696 
697  int code = pthread_cancel(d->thread_id);
698  if (code) {
699  qWarning("QThread::start: Thread termination error: %s",
700  qPrintable(qt_error_string((code))));
701  } else {
702  d->terminated = true;
703  }
704 }
705 
706 bool QThread::wait(unsigned long time)
707 {
708  Q_D(QThread);
709  QMutexLocker locker(&d->mutex);
710 
711  if (d->thread_id == pthread_self()) {
712  qWarning("QThread::wait: Thread tried to wait on itself");
713  return false;
714  }
715 
716  if (d->finished || !d->running)
717  return true;
718 
719  while (d->running) {
720  if (!d->thread_done.wait(locker.mutex(), time))
721  return false;
722  }
723  return true;
724 }
725 
727 {
728  QThread *thr = currentThread();
729  Q_ASSERT_X(thr != 0, "QThread::setTerminationEnabled()",
730  "Current thread was not started with QThread.");
731 
732  Q_UNUSED(thr)
733  pthread_setcancelstate(enabled ? PTHREAD_CANCEL_ENABLE : PTHREAD_CANCEL_DISABLE, NULL);
734  if (enabled)
736 }
737 
739 {
740  Q_D(QThread);
741  QMutexLocker locker(&d->mutex);
742  if (!d->running) {
743  qWarning("QThread::setPriority: Cannot set priority, thread is not running");
744  return;
745  }
746 
747  d->priority = priority;
748 
749  // copied from start() with a few modifications:
750 
751 #ifdef QT_HAS_THREAD_PRIORITY_SCHEDULING
752  int sched_policy;
753  sched_param param;
754 
755  if (pthread_getschedparam(d->thread_id, &sched_policy, &param) != 0) {
756  // failed to get the scheduling policy, don't bother setting
757  // the priority
758  qWarning("QThread::setPriority: Cannot get scheduler parameters");
759  return;
760  }
761 
762  int prio;
763  if (!calculateUnixPriority(priority, &sched_policy, &prio)) {
764  // failed to get the scheduling parameters, don't
765  // bother setting the priority
766  qWarning("QThread::setPriority: Cannot determine scheduler priority range");
767  return;
768  }
769 
770  param.sched_priority = prio;
771  int status = pthread_setschedparam(d->thread_id, sched_policy, &param);
772 
773 # ifdef SCHED_IDLE
774  // were we trying to set to idle priority and failed?
775  if (status == -1 && sched_policy == SCHED_IDLE && errno == EINVAL) {
776  // reset to lowest priority possible
777  pthread_getschedparam(d->thread_id, &sched_policy, &param);
778  param.sched_priority = sched_get_priority_min(sched_policy);
779  pthread_setschedparam(d->thread_id, sched_policy, &param);
780  }
781 # else
782  Q_UNUSED(status);
783 # endif // SCHED_IDLE
784 #endif
785 }
786 
787 #endif // QT_NO_THREAD
788 
790 
double d
Definition: qnumeric_p.h:62
QString qt_error_string(int errorCode)
Definition: qglobal.cpp:2600
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
virtual void run()
The starting point for the thread.
Definition: qthread.cpp:628
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
static void finish(void **)
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
pthread_t thread_id
Definition: qthread_p.h:161
static void * start(void *arg)
void finished()
This signal is emitted when the thread has finished executing.
void pthread_cleanup_pop(int)
void unlock()
Unlocks this mutex locker.
Definition: qmutex.h:117
static LibLoadStatus status
Definition: qlocale_icu.cpp:69
static QThread * theMainThread
long ASN1_INTEGER_get ASN1_INTEGER * a
QVector< void * > tls
Definition: qthread_p.h:268
bool isAdopted
Definition: qthread_p.h:269
static void clearCurrentThreadData()
The QString class provides a Unicode character string.
Definition: qstring.h:83
void started()
This signal is emitted when the thread starts executing.
static bool calculateUnixPriority(int priority, int *sched_policy, int *sched_priority)
#define Q_DESTRUCTOR_FUNCTION(AFUNC)
Definition: qglobal.h:839
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
#define Q_D(Class)
Definition: qglobal.h:2482
Priority
This enum type indicates how the operating system should schedule newly created threads.
Definition: qthread.h:70
static QObjectPrivate * get(QObject *o)
Definition: qobject_p.h:177
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
static void setCurrentThreadName(pthread_t threadId, const char *name)
void deref()
Definition: qthread.cpp:125
int pthread_cancel(pthread_t)
Priority priority() const
Returns the priority for a running thread.
Definition: qthread.cpp:718
static void yieldCurrentThread()
Yields execution of the current thread to another runnable thread, if any.
void relock()
Relocks an unlocked mutex locker.
Definition: qmutex.h:125
static void msleep(unsigned long)
Forces the current thread to sleep for msecs milliseconds.
#define QT_RETHROW
Definition: qglobal.h:1539
static QThreadData * get2(QThread *thread)
Definition: qthread_p.h:219
#define SCHED_IDLE
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
static bool isEmpty(const char *str)
QThreadData(int initialRefCount=1)
Definition: qthread.cpp:79
static bool activateCallbacks(Callback, void **)
Definition: qglobal.cpp:3653
static void destroy_current_thread_data_key()
int pthread_setcancelstate(int, int *)
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
void pthread_testcancel(void)
static bool init
const char * name
#define emit
Definition: qobjectdefs.h:76
Q_CORE_EXPORT void qWarning(const char *,...)
static const char * data(const QByteArray &arr)
int mib
static void sendPostedEvents()
void * HANDLE
Definition: qnamespace.h:1671
static void create_current_thread_data_key()
#define QT_CATCH(A)
Definition: qglobal.h:1537
QByteArray toLocal8Bit() const Q_REQUIRED_RESULT
Returns the local 8-bit representation of the string as a QByteArray.
Definition: qstring.cpp:4049
bool quitNow
Definition: qthread_p.h:262
static pthread_once_t current_thread_data_once
QThreadData * data
Definition: qthread_p.h:185
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
Definition: qmutex.h:101
void terminated()
This signal is emitted when the thread is terminated.
void ref()
Definition: qthread.cpp:117
void pthread_cleanup_push(void(*)(void *), void *)
static pthread_key_t current_thread_data_key
QWaitCondition thread_done
Definition: qthread_p.h:162
static void setTerminationEnabled(bool enabled=true)
Enables or disables termination of the current thread based on the enabled parameter.
void start(Priority=InheritPriority)
Begins execution of the thread by calling run().
bool wait(unsigned long time=ULONG_MAX)
Blocks the thread until either of these conditions is met:
static void thread_sleep(struct timespec *ti)
static void set_thread_data(QThreadData *data)
QMutex mutex
Definition: qthread_p.h:145
const char * className() const
Returns the class name.
Definition: qobjectdefs.h:491
QString objectName() const
static QThreadData * current()
#define Q_LIKELY(x)
Hints to the compiler that the enclosed condition, expr, is likely to evaluate to true...
Definition: qglobal.h:820
QThread::Priority priority
Definition: qthread_p.h:156
static void destroy_current_thread_data(void *p)
void terminate()
Terminates the execution of the thread.
static const MacVersion MacintoshVersion
the version of the Macintosh operating system on which the application is run (Mac only)...
Definition: qglobal.h:1646
static void sleep(unsigned long)
Forces the current thread to sleep for secs seconds.
static void finish(void *)
static void createEventDispatcher(QThreadData *data)
QThread * thread
Definition: qthread_p.h:260
#define qPrintable(string)
Definition: qglobal.h:1750
The QThread class provides a platform-independent way to manage threads.
Definition: qthread.h:59
Qt::HANDLE threadId
Definition: qthread_p.h:261
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
QAbstractEventDispatcher * eventDispatcher
Definition: qthread_p.h:264
#define QT_TRY
Definition: qglobal.h:1536
static QThreadData * get_thread_data()
void setPriority(Priority priority)
This function sets the priority for a running thread.
static void clear_thread_data()
static void usleep(unsigned long)
Forces the current thread to sleep for usecs microseconds.
QMutex * mutex() const
Returns a pointer to the mutex that was locked in the constructor.
Definition: qmutex.h:140
#define enabled
The QAbstractEventDispatcher class provides an interface to manage Qt&#39;s event queue.
virtual const QMetaObject * metaObject() const
Returns a pointer to the meta-object of this object.
int errno
static Qt::HANDLE currentThreadId()
Returns the thread handle of the currently executing thread.
int pthread_attr_setinheritsched(pthread_attr_t *, int)
static int idealThreadCount()
Returns the ideal number of threads that can be run on the system.