2 * Copyright (c) 2013 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #include "kern_internal.h"
30 #include <kern/debug.h>
31 #include <kern/assert.h>
34 thread_qos_get_pthread_priority(int qos
)
36 /* Map the buckets we have in pthread_priority_t into a QoS tier. */
38 case THREAD_QOS_USER_INTERACTIVE
: return _pthread_priority_make_newest(QOS_CLASS_USER_INTERACTIVE
, 0, 0);
39 case THREAD_QOS_USER_INITIATED
: return _pthread_priority_make_newest(QOS_CLASS_USER_INITIATED
, 0, 0);
40 case THREAD_QOS_LEGACY
: return _pthread_priority_make_newest(QOS_CLASS_DEFAULT
, 0, 0);
41 case THREAD_QOS_UTILITY
: return _pthread_priority_make_newest(QOS_CLASS_UTILITY
, 0, 0);
42 case THREAD_QOS_BACKGROUND
: return _pthread_priority_make_newest(QOS_CLASS_BACKGROUND
, 0, 0);
43 case THREAD_QOS_MAINTENANCE
: return _pthread_priority_make_newest(QOS_CLASS_MAINTENANCE
, 0, 0);
44 default: return _pthread_priority_make_newest(QOS_CLASS_UNSPECIFIED
, 0, 0);
49 thread_qos_get_class_index(int qos
)
52 case THREAD_QOS_USER_INTERACTIVE
: return 0;
53 case THREAD_QOS_USER_INITIATED
: return 1;
54 case THREAD_QOS_LEGACY
: return 2;
55 case THREAD_QOS_UTILITY
: return 3;
56 case THREAD_QOS_BACKGROUND
: return 4;
57 case THREAD_QOS_MAINTENANCE
: return 5;
63 pthread_priority_get_thread_qos(pthread_priority_t priority
)
65 /* Map the buckets we have in pthread_priority_t into a QoS tier. */
66 switch (_pthread_priority_get_qos_newest(priority
)) {
67 case QOS_CLASS_USER_INTERACTIVE
: return THREAD_QOS_USER_INTERACTIVE
;
68 case QOS_CLASS_USER_INITIATED
: return THREAD_QOS_USER_INITIATED
;
69 case QOS_CLASS_DEFAULT
: return THREAD_QOS_LEGACY
;
70 case QOS_CLASS_UTILITY
: return THREAD_QOS_UTILITY
;
71 case QOS_CLASS_BACKGROUND
: return THREAD_QOS_BACKGROUND
;
72 case QOS_CLASS_MAINTENANCE
: return THREAD_QOS_MAINTENANCE
;
73 default: return THREAD_QOS_UNSPECIFIED
;
78 pthread_priority_get_class_index(pthread_priority_t priority
)
80 return qos_class_get_class_index(_pthread_priority_get_qos_newest(priority
));
84 class_index_get_pthread_priority(int index
)
88 case 0: qos
= QOS_CLASS_USER_INTERACTIVE
; break;
89 case 1: qos
= QOS_CLASS_USER_INITIATED
; break;
90 case 2: qos
= QOS_CLASS_DEFAULT
; break;
91 case 3: qos
= QOS_CLASS_UTILITY
; break;
92 case 4: qos
= QOS_CLASS_BACKGROUND
; break;
93 case 5: qos
= QOS_CLASS_MAINTENANCE
; break;
94 case 6: assert(index
!= 6); // EVENT_MANAGER should be handled specially
96 /* Return the utility band if we don't understand the input. */
97 qos
= QOS_CLASS_UTILITY
;
100 pthread_priority_t priority
;
101 priority
= _pthread_priority_make_newest(qos
, 0, 0);
107 class_index_get_thread_qos(int class)
111 case 0: thread_qos
= THREAD_QOS_USER_INTERACTIVE
; break;
112 case 1: thread_qos
= THREAD_QOS_USER_INITIATED
; break;
113 case 2: thread_qos
= THREAD_QOS_LEGACY
; break;
114 case 3: thread_qos
= THREAD_QOS_UTILITY
; break;
115 case 4: thread_qos
= THREAD_QOS_BACKGROUND
; break;
116 case 5: thread_qos
= THREAD_QOS_MAINTENANCE
; break;
117 case 6: thread_qos
= THREAD_QOS_LAST
; break;
119 thread_qos
= THREAD_QOS_LAST
;
125 qos_class_get_class_index(int qos
)
128 case QOS_CLASS_USER_INTERACTIVE
: return 0;
129 case QOS_CLASS_USER_INITIATED
: return 1;
130 case QOS_CLASS_DEFAULT
: return 2;
131 case QOS_CLASS_UTILITY
: return 3;
132 case QOS_CLASS_BACKGROUND
: return 4;
133 case QOS_CLASS_MAINTENANCE
: return 5;
135 /* Return the default band if we don't understand the input. */
141 * Shims to help the kernel understand pthread_priority_t
145 _thread_qos_from_pthread_priority(unsigned long priority
, unsigned long *flags
)
148 *flags
= (int)_pthread_priority_get_flags(priority
);
150 int thread_qos
= pthread_priority_get_thread_qos(priority
);
151 if (thread_qos
== THREAD_QOS_UNSPECIFIED
&& flags
!= NULL
){
152 *flags
|= _PTHREAD_PRIORITY_EVENT_MANAGER_FLAG
;
158 _pthread_priority_canonicalize(pthread_priority_t priority
, boolean_t for_propagation
)
160 qos_class_t qos_class
;
162 unsigned long flags
= _pthread_priority_get_flags(priority
);
163 _pthread_priority_split_newest(priority
, qos_class
, relpri
);
165 if (for_propagation
) {
167 if (relpri
> 0 || relpri
< -15) relpri
= 0;
169 if (qos_class
== QOS_CLASS_UNSPECIFIED
) {
170 flags
= _PTHREAD_PRIORITY_EVENT_MANAGER_FLAG
;
171 } else if (flags
& (_PTHREAD_PRIORITY_EVENT_MANAGER_FLAG
|_PTHREAD_PRIORITY_SCHED_PRI_FLAG
)){
172 flags
= _PTHREAD_PRIORITY_EVENT_MANAGER_FLAG
;
173 qos_class
= QOS_CLASS_UNSPECIFIED
;
175 flags
&= _PTHREAD_PRIORITY_OVERCOMMIT_FLAG
|_PTHREAD_PRIORITY_EVENT_MANAGER_FLAG
;
181 return _pthread_priority_make_newest(qos_class
, relpri
, flags
);