#include <kern/assert.h>
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);
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)) {
}
}
+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) {
}
int
-qos_get_class_index(int qos){
+class_index_get_thread_qos(int class)
+{
+ 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_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;
}
}
-int
-pthread_priority_get_class_index(pthread_priority_t priority)
-{
- return qos_get_class_index(_pthread_priority_get_qos_newest(priority));
-}
+/**
+ * Shims to help the kernel understand pthread_priority_t
+ */
integer_t
-_thread_qos_from_pthread_priority(unsigned long priority, unsigned long *flags){
- if (flags){
- *flags = (int)_pthread_priority_get_flags(priority) >> _PTHREAD_PRIORITY_FLAGS_SHIFT;
+_thread_qos_from_pthread_priority(unsigned long priority, unsigned long *flags)
+{
+ if (flags != NULL){
+ *flags = (int)_pthread_priority_get_flags(priority);
}
- return pthread_priority_get_qos_class(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);
}