X-Git-Url: https://git.saurik.com/apple/libpthread.git/blobdiff_plain/f1a1da6cf65a9d0e6858678f6c259025cf5d27fd..76b7b9a2a65d05f65ded82a6675bf63a7f569766:/kern/kern_policy.c diff --git a/kern/kern_policy.c b/kern/kern_policy.c index 23fb0d0..98e0c61 100644 --- a/kern/kern_policy.c +++ b/kern/kern_policy.c @@ -28,12 +28,13 @@ #include "kern_internal.h" #include +#include pthread_priority_t -pthread_qos_class_get_priority(int qos) +thread_qos_get_pthread_priority(int qos) { - /* Map the buckets we have in pthread_priority_t into a QoS tier. */ - switch (qos) { + /* Map the buckets we have in pthread_priority_t into a QoS tier. */ + switch (qos) { case THREAD_QOS_USER_INTERACTIVE: return _pthread_priority_make_newest(QOS_CLASS_USER_INTERACTIVE, 0, 0); case THREAD_QOS_USER_INITIATED: return _pthread_priority_make_newest(QOS_CLASS_USER_INITIATED, 0, 0); case THREAD_QOS_LEGACY: return _pthread_priority_make_newest(QOS_CLASS_DEFAULT, 0, 0); @@ -41,11 +42,25 @@ pthread_qos_class_get_priority(int qos) case THREAD_QOS_BACKGROUND: return _pthread_priority_make_newest(QOS_CLASS_BACKGROUND, 0, 0); case THREAD_QOS_MAINTENANCE: return _pthread_priority_make_newest(QOS_CLASS_MAINTENANCE, 0, 0); default: return _pthread_priority_make_newest(QOS_CLASS_UNSPECIFIED, 0, 0); + } +} + +int +thread_qos_get_class_index(int qos) +{ + switch (qos) { + case THREAD_QOS_USER_INTERACTIVE: return 0; + case THREAD_QOS_USER_INITIATED: return 1; + case THREAD_QOS_LEGACY: return 2; + case THREAD_QOS_UTILITY: return 3; + case THREAD_QOS_BACKGROUND: return 4; + case THREAD_QOS_MAINTENANCE: return 5; + default: return 2; } } int -pthread_priority_get_qos_class(pthread_priority_t priority) +pthread_priority_get_thread_qos(pthread_priority_t priority) { /* Map the buckets we have in pthread_priority_t into a QoS tier. */ switch (_pthread_priority_get_qos_newest(priority)) { @@ -59,8 +74,14 @@ pthread_priority_get_qos_class(pthread_priority_t priority) } } +int +pthread_priority_get_class_index(pthread_priority_t priority) +{ + return qos_class_get_class_index(_pthread_priority_get_qos_newest(priority)); +} + pthread_priority_t -pthread_priority_from_class_index(int index) +class_index_get_pthread_priority(int index) { qos_class_t qos; switch (index) { @@ -70,6 +91,7 @@ pthread_priority_from_class_index(int index) case 3: qos = QOS_CLASS_UTILITY; break; case 4: qos = QOS_CLASS_BACKGROUND; break; case 5: qos = QOS_CLASS_MAINTENANCE; break; + case 6: assert(index != 6); // EVENT_MANAGER should be handled specially default: /* Return the utility band if we don't understand the input. */ qos = QOS_CLASS_UTILITY; @@ -82,9 +104,27 @@ pthread_priority_from_class_index(int index) } int -pthread_priority_get_class_index(pthread_priority_t priority) +class_index_get_thread_qos(int class) { - switch (_pthread_priority_get_qos_newest(priority)) { + int thread_qos; + switch (class) { + case 0: thread_qos = THREAD_QOS_USER_INTERACTIVE; break; + case 1: thread_qos = THREAD_QOS_USER_INITIATED; break; + case 2: thread_qos = THREAD_QOS_LEGACY; break; + case 3: thread_qos = THREAD_QOS_UTILITY; break; + case 4: thread_qos = THREAD_QOS_BACKGROUND; break; + case 5: thread_qos = THREAD_QOS_MAINTENANCE; break; + case 6: thread_qos = THREAD_QOS_LAST; break; + default: + thread_qos = THREAD_QOS_LAST; + } + return thread_qos; +} + +int +qos_class_get_class_index(int qos) +{ + switch (qos){ case QOS_CLASS_USER_INTERACTIVE: return 0; case QOS_CLASS_USER_INITIATED: return 1; case QOS_CLASS_DEFAULT: return 2; @@ -92,7 +132,51 @@ pthread_priority_get_class_index(pthread_priority_t priority) case QOS_CLASS_BACKGROUND: return 4; case QOS_CLASS_MAINTENANCE: return 5; default: - /* Return the utility band if we don't understand the input. */ + /* Return the default band if we don't understand the input. */ return 2; } } + +/** + * Shims to help the kernel understand pthread_priority_t + */ + +integer_t +_thread_qos_from_pthread_priority(unsigned long priority, unsigned long *flags) +{ + if (flags != NULL){ + *flags = (int)_pthread_priority_get_flags(priority); + } + int thread_qos = pthread_priority_get_thread_qos(priority); + if (thread_qos == THREAD_QOS_UNSPECIFIED && flags != NULL){ + *flags |= _PTHREAD_PRIORITY_EVENT_MANAGER_FLAG; + } + return thread_qos; +} + +pthread_priority_t +_pthread_priority_canonicalize(pthread_priority_t priority, boolean_t for_propagation) +{ + qos_class_t qos_class; + int relpri; + unsigned long flags = _pthread_priority_get_flags(priority); + _pthread_priority_split_newest(priority, qos_class, relpri); + + if (for_propagation) { + flags = 0; + if (relpri > 0 || relpri < -15) relpri = 0; + } else { + if (qos_class == QOS_CLASS_UNSPECIFIED) { + flags = _PTHREAD_PRIORITY_EVENT_MANAGER_FLAG; + } else if (flags & (_PTHREAD_PRIORITY_EVENT_MANAGER_FLAG|_PTHREAD_PRIORITY_SCHED_PRI_FLAG)){ + flags = _PTHREAD_PRIORITY_EVENT_MANAGER_FLAG; + qos_class = QOS_CLASS_UNSPECIFIED; + } else { + flags &= _PTHREAD_PRIORITY_OVERCOMMIT_FLAG|_PTHREAD_PRIORITY_EVENT_MANAGER_FLAG; + } + + relpri = 0; + } + + return _pthread_priority_make_newest(qos_class, relpri, flags); +}