]> git.saurik.com Git - apple/libpthread.git/blame - kern/kern_policy.c
libpthread-218.1.3.tar.gz
[apple/libpthread.git] / kern / kern_policy.c
CommitLineData
f1a1da6c
A
1/*
2 * Copyright (c) 2013 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29#include "kern_internal.h"
30#include <kern/debug.h>
964d3577 31#include <kern/assert.h>
f1a1da6c
A
32
33pthread_priority_t
2546420a 34thread_qos_get_pthread_priority(int qos)
f1a1da6c 35{
2546420a
A
36 /* Map the buckets we have in pthread_priority_t into a QoS tier. */
37 switch (qos) {
f1a1da6c
A
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);
2546420a
A
45 }
46}
47
48int
49thread_qos_get_class_index(int qos)
50{
51 switch (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;
58 default: return 2;
f1a1da6c
A
59 }
60}
61
62int
2546420a 63pthread_priority_get_thread_qos(pthread_priority_t priority)
f1a1da6c
A
64{
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;
74 }
75}
76
2546420a
A
77int
78pthread_priority_get_class_index(pthread_priority_t priority)
79{
80 return qos_class_get_class_index(_pthread_priority_get_qos_newest(priority));
81}
82
f1a1da6c 83pthread_priority_t
2546420a 84class_index_get_pthread_priority(int index)
f1a1da6c
A
85{
86 qos_class_t qos;
87 switch (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;
964d3577 94 case 6: assert(index != 6); // EVENT_MANAGER should be handled specially
f1a1da6c
A
95 default:
96 /* Return the utility band if we don't understand the input. */
97 qos = QOS_CLASS_UTILITY;
98 }
99
100 pthread_priority_t priority;
101 priority = _pthread_priority_make_newest(qos, 0, 0);
102
103 return priority;
104}
105
106int
2546420a
A
107class_index_get_thread_qos(int class)
108{
109 int thread_qos;
110 switch (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;
118 default:
119 thread_qos = THREAD_QOS_LAST;
120 }
121 return thread_qos;
122}
123
124int
125qos_class_get_class_index(int qos)
126{
964d3577 127 switch (qos){
f1a1da6c
A
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;
134 default:
2546420a 135 /* Return the default band if we don't understand the input. */
f1a1da6c
A
136 return 2;
137 }
138}
964d3577 139
2546420a
A
140/**
141 * Shims to help the kernel understand pthread_priority_t
142 */
964d3577
A
143
144integer_t
2546420a
A
145_thread_qos_from_pthread_priority(unsigned long priority, unsigned long *flags)
146{
147 if (flags != NULL){
148 *flags = (int)_pthread_priority_get_flags(priority);
964d3577 149 }
2546420a
A
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;
153 }
154 return thread_qos;
155}
156
157pthread_priority_t
158_pthread_priority_canonicalize(pthread_priority_t priority, boolean_t for_propagation)
159{
160 qos_class_t qos_class;
161 int relpri;
162 unsigned long flags = _pthread_priority_get_flags(priority);
163 _pthread_priority_split_newest(priority, qos_class, relpri);
164
165 if (for_propagation) {
166 flags = 0;
167 if (relpri > 0 || relpri < -15) relpri = 0;
168 } else {
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;
174 } else {
175 flags &= _PTHREAD_PRIORITY_OVERCOMMIT_FLAG|_PTHREAD_PRIORITY_EVENT_MANAGER_FLAG;
176 }
177
178 relpri = 0;
179 }
180
181 return _pthread_priority_make_newest(qos_class, relpri, flags);
964d3577 182}