2 * Copyright (c) 2008-2016 Apple Inc. All rights reserved.
4 * @APPLE_APACHE_LICENSE_HEADER_START@
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * @APPLE_APACHE_LICENSE_HEADER_END@
22 * IMPORTANT: This header file describes INTERNAL interfaces to libdispatch
23 * which are subject to change in future releases of Mac OS X. Any applications
24 * relying on these interfaces WILL break.
27 #ifndef __DISPATCH_SHIMS_PRIORITY__
28 #define __DISPATCH_SHIMS_PRIORITY__
30 #if HAVE_PTHREAD_QOS_H && __has_include(<pthread/qos_private.h>)
31 #include <pthread/qos.h>
32 #include <pthread/qos_private.h>
33 #ifndef _PTHREAD_PRIORITY_OVERCOMMIT_FLAG
34 #define _PTHREAD_PRIORITY_OVERCOMMIT_FLAG 0x80000000
36 #ifndef _PTHREAD_PRIORITY_SCHED_PRI_FLAG
37 #define _PTHREAD_PRIORITY_SCHED_PRI_FLAG 0x20000000
39 #ifndef _PTHREAD_PRIORITY_DEFAULTQUEUE_FLAG
40 #define _PTHREAD_PRIORITY_DEFAULTQUEUE_FLAG 0x04000000
42 #ifndef _PTHREAD_PRIORITY_EVENT_MANAGER_FLAG
43 #define _PTHREAD_PRIORITY_EVENT_MANAGER_FLAG 0x02000000
45 #ifndef _PTHREAD_PRIORITY_NEEDS_UNBIND_FLAG
46 #define _PTHREAD_PRIORITY_NEEDS_UNBIND_FLAG 0x01000000
48 #else // HAVE_PTHREAD_QOS_H
49 OS_ENUM(qos_class
, unsigned int,
50 QOS_CLASS_USER_INTERACTIVE
= 0x21,
51 QOS_CLASS_USER_INITIATED
= 0x19,
52 QOS_CLASS_DEFAULT
= 0x15,
53 QOS_CLASS_UTILITY
= 0x11,
54 QOS_CLASS_BACKGROUND
= 0x09,
55 QOS_CLASS_MAINTENANCE
= 0x05,
56 QOS_CLASS_UNSPECIFIED
= 0x00,
58 typedef unsigned long pthread_priority_t
;
59 #define QOS_MIN_RELATIVE_PRIORITY (-15)
60 #define _PTHREAD_PRIORITY_FLAGS_MASK (~0xffffff)
61 #define _PTHREAD_PRIORITY_QOS_CLASS_MASK 0x00ffff00
62 #define _PTHREAD_PRIORITY_QOS_CLASS_SHIFT (8ull)
63 #define _PTHREAD_PRIORITY_PRIORITY_MASK 0x000000ff
64 #define _PTHREAD_PRIORITY_OVERCOMMIT_FLAG 0x80000000
65 #define _PTHREAD_PRIORITY_SCHED_PRI_FLAG 0x20000000
66 #define _PTHREAD_PRIORITY_DEFAULTQUEUE_FLAG 0x04000000
67 #define _PTHREAD_PRIORITY_EVENT_MANAGER_FLAG 0x02000000
68 #define _PTHREAD_PRIORITY_NEEDS_UNBIND_FLAG 0x01000000
69 #define _PTHREAD_PRIORITY_ENFORCE_FLAG 0x10000000
71 #endif // HAVE_PTHREAD_QOS_H
73 typedef uint32_t dispatch_qos_t
;
74 typedef uint32_t dispatch_priority_t
;
75 typedef uint32_t dispatch_priority_t
;
76 typedef uint16_t dispatch_priority_requested_t
;
78 #define DISPATCH_QOS_UNSPECIFIED ((dispatch_qos_t)0)
79 #define DISPATCH_QOS_MAINTENANCE ((dispatch_qos_t)1)
80 #define DISPATCH_QOS_BACKGROUND ((dispatch_qos_t)2)
81 #define DISPATCH_QOS_UTILITY ((dispatch_qos_t)3)
82 #define DISPATCH_QOS_DEFAULT ((dispatch_qos_t)4)
83 #define DISPATCH_QOS_USER_INITIATED ((dispatch_qos_t)5)
84 #define DISPATCH_QOS_USER_INTERACTIVE ((dispatch_qos_t)6)
85 #define DISPATCH_QOS_MAX DISPATCH_QOS_USER_INTERACTIVE
86 #define DISPATCH_QOS_SATURATED ((dispatch_qos_t)15)
88 #define DISPATCH_PRIORITY_RELPRI_MASK ((dispatch_priority_t)0x000000ff)
89 #define DISPATCH_PRIORITY_RELPRI_SHIFT 0
90 #define DISPATCH_PRIORITY_QOS_MASK ((dispatch_priority_t)0x0000ff00)
91 #define DISPATCH_PRIORITY_QOS_SHIFT 8
92 #define DISPATCH_PRIORITY_REQUESTED_MASK ((dispatch_priority_t)0x0000ffff)
93 #define DISPATCH_PRIORITY_OVERRIDE_MASK ((dispatch_priority_t)0x00ff0000)
94 #define DISPATCH_PRIORITY_OVERRIDE_SHIFT 16
95 #define DISPATCH_PRIORITY_FLAGS_MASK ((dispatch_priority_t)0xff000000)
97 #define DISPATCH_PRIORITY_SATURATED_OVERRIDE ((dispatch_priority_t)0x000f0000)
99 #define DISPATCH_PRIORITY_FLAG_OVERCOMMIT ((dispatch_priority_t)0x80000000) // _PTHREAD_PRIORITY_OVERCOMMIT_FLAG
100 #define DISPATCH_PRIORITY_FLAG_DEFAULTQUEUE ((dispatch_priority_t)0x04000000) // _PTHREAD_PRIORITY_DEFAULTQUEUE_FLAG
101 #define DISPATCH_PRIORITY_FLAG_MANAGER ((dispatch_priority_t)0x02000000) // _PTHREAD_PRIORITY_EVENT_MANAGER_FLAG
102 #define DISPATCH_PRIORITY_PTHREAD_PRIORITY_FLAGS_MASK \
103 (DISPATCH_PRIORITY_FLAG_OVERCOMMIT | DISPATCH_PRIORITY_FLAG_DEFAULTQUEUE | \
104 DISPATCH_PRIORITY_FLAG_MANAGER)
106 // not passed to pthread
107 #define DISPATCH_PRIORITY_FLAG_INHERIT ((dispatch_priority_t)0x40000000) // _PTHREAD_PRIORITY_INHERIT_FLAG
108 #define DISPATCH_PRIORITY_FLAG_ENFORCE ((dispatch_priority_t)0x10000000) // _PTHREAD_PRIORITY_ENFORCE_FLAG
109 #define DISPATCH_PRIORITY_FLAG_ROOTQUEUE ((dispatch_priority_t)0x20000000) // _PTHREAD_PRIORITY_ROOTQUEUE_FLAG
111 #pragma mark dispatch_qos
113 DISPATCH_ALWAYS_INLINE
114 static inline dispatch_qos_t
115 _dispatch_qos_from_qos_class(qos_class_t cls
)
117 switch ((unsigned int)cls
) {
118 case QOS_CLASS_USER_INTERACTIVE
: return DISPATCH_QOS_USER_INTERACTIVE
;
119 case QOS_CLASS_USER_INITIATED
: return DISPATCH_QOS_USER_INITIATED
;
120 case QOS_CLASS_DEFAULT
: return DISPATCH_QOS_DEFAULT
;
121 case QOS_CLASS_UTILITY
: return DISPATCH_QOS_UTILITY
;
122 case QOS_CLASS_BACKGROUND
: return DISPATCH_QOS_BACKGROUND
;
123 case QOS_CLASS_MAINTENANCE
: return DISPATCH_QOS_MAINTENANCE
;
124 default: return DISPATCH_QOS_UNSPECIFIED
;
128 DISPATCH_ALWAYS_INLINE
129 static inline qos_class_t
130 _dispatch_qos_to_qos_class(dispatch_qos_t qos
)
133 case DISPATCH_QOS_USER_INTERACTIVE
: return QOS_CLASS_USER_INTERACTIVE
;
134 case DISPATCH_QOS_USER_INITIATED
: return QOS_CLASS_USER_INITIATED
;
135 case DISPATCH_QOS_DEFAULT
: return QOS_CLASS_DEFAULT
;
136 case DISPATCH_QOS_UTILITY
: return QOS_CLASS_UTILITY
;
137 case DISPATCH_QOS_BACKGROUND
: return QOS_CLASS_BACKGROUND
;
138 case DISPATCH_QOS_MAINTENANCE
: return (qos_class_t
)QOS_CLASS_MAINTENANCE
;
139 default: return QOS_CLASS_UNSPECIFIED
;
143 DISPATCH_ALWAYS_INLINE
144 static inline dispatch_qos_t
145 _dispatch_qos_from_queue_priority(long priority
)
148 case DISPATCH_QUEUE_PRIORITY_BACKGROUND
: return DISPATCH_QOS_BACKGROUND
;
149 case DISPATCH_QUEUE_PRIORITY_NON_INTERACTIVE
: return DISPATCH_QOS_UTILITY
;
150 case DISPATCH_QUEUE_PRIORITY_LOW
: return DISPATCH_QOS_UTILITY
;
151 case DISPATCH_QUEUE_PRIORITY_DEFAULT
: return DISPATCH_QOS_DEFAULT
;
152 case DISPATCH_QUEUE_PRIORITY_HIGH
: return DISPATCH_QOS_USER_INITIATED
;
153 default: return _dispatch_qos_from_qos_class((qos_class_t
)priority
);
157 DISPATCH_ALWAYS_INLINE
158 static inline dispatch_qos_t
159 _dispatch_qos_from_pp(pthread_priority_t pp
)
161 pp
&= _PTHREAD_PRIORITY_QOS_CLASS_MASK
;
162 pp
>>= _PTHREAD_PRIORITY_QOS_CLASS_SHIFT
;
163 return (dispatch_qos_t
)__builtin_ffs((int)pp
);
166 DISPATCH_ALWAYS_INLINE
167 static inline pthread_priority_t
168 _dispatch_qos_to_pp(dispatch_qos_t qos
)
170 pthread_priority_t pp
;
171 pp
= 1ul << ((qos
- 1) + _PTHREAD_PRIORITY_QOS_CLASS_SHIFT
);
172 return pp
| _PTHREAD_PRIORITY_PRIORITY_MASK
;
175 // including maintenance
176 DISPATCH_ALWAYS_INLINE
178 _dispatch_qos_is_background(dispatch_qos_t qos
)
180 return qos
&& qos
<= DISPATCH_QOS_BACKGROUND
;
183 #pragma mark dispatch_priority
185 #define _dispatch_priority_make(qos, relpri) \
186 (qos ? ((((qos) << DISPATCH_PRIORITY_QOS_SHIFT) & DISPATCH_PRIORITY_QOS_MASK) | \
187 ((dispatch_priority_t)(relpri - 1) & DISPATCH_PRIORITY_RELPRI_MASK)) : 0)
189 DISPATCH_ALWAYS_INLINE
190 static inline dispatch_priority_t
191 _dispatch_priority_with_override_qos(dispatch_priority_t pri
,
194 pri
&= ~DISPATCH_PRIORITY_OVERRIDE_MASK
;
195 pri
|= oqos
<< DISPATCH_PRIORITY_OVERRIDE_SHIFT
;
199 DISPATCH_ALWAYS_INLINE
201 _dispatch_priority_relpri(dispatch_priority_t dbp
)
203 if (dbp
& DISPATCH_PRIORITY_QOS_MASK
) {
204 return (int8_t)(dbp
& DISPATCH_PRIORITY_RELPRI_MASK
) + 1;
209 DISPATCH_ALWAYS_INLINE
210 static inline dispatch_qos_t
211 _dispatch_priority_qos(dispatch_priority_t dbp
)
213 dbp
&= DISPATCH_PRIORITY_QOS_MASK
;
214 return dbp
>> DISPATCH_PRIORITY_QOS_SHIFT
;
217 DISPATCH_ALWAYS_INLINE
218 static inline dispatch_qos_t
219 _dispatch_priority_override_qos(dispatch_priority_t dbp
)
221 dbp
&= DISPATCH_PRIORITY_OVERRIDE_MASK
;
222 return dbp
>> DISPATCH_PRIORITY_OVERRIDE_SHIFT
;
225 DISPATCH_ALWAYS_INLINE
226 static inline dispatch_priority_t
227 _dispatch_priority_from_pp_impl(pthread_priority_t pp
, bool keep_flags
)
229 dispatch_assert(!(pp
& _PTHREAD_PRIORITY_SCHED_PRI_FLAG
));
231 dispatch_priority_t dbp
;
233 dbp
= pp
& (DISPATCH_PRIORITY_PTHREAD_PRIORITY_FLAGS_MASK
|
234 DISPATCH_PRIORITY_RELPRI_MASK
);
236 dbp
= pp
& DISPATCH_PRIORITY_RELPRI_MASK
;
239 dbp
|= _dispatch_qos_from_pp(pp
) << DISPATCH_PRIORITY_QOS_SHIFT
;
242 #define _dispatch_priority_from_pp(pp) \
243 _dispatch_priority_from_pp_impl(pp, true)
244 #define _dispatch_priority_from_pp_strip_flags(pp) \
245 _dispatch_priority_from_pp_impl(pp, false)
247 DISPATCH_ALWAYS_INLINE
248 static inline pthread_priority_t
249 _dispatch_priority_to_pp_impl(dispatch_priority_t dbp
, bool keep_flags
)
251 pthread_priority_t pp
;
253 pp
= dbp
& (DISPATCH_PRIORITY_PTHREAD_PRIORITY_FLAGS_MASK
|
254 DISPATCH_PRIORITY_RELPRI_MASK
);
256 pp
= dbp
& DISPATCH_PRIORITY_RELPRI_MASK
;
258 dispatch_qos_t qos
= _dispatch_priority_qos(dbp
);
260 pp
|= (1ul << ((qos
- 1) + _PTHREAD_PRIORITY_QOS_CLASS_SHIFT
));
264 #define _dispatch_priority_to_pp(pp) \
265 _dispatch_priority_to_pp_impl(pp, true)
266 #define _dispatch_priority_to_pp_strip_flags(pp) \
267 _dispatch_priority_to_pp_impl(pp, false)
269 #endif // __DISPATCH_SHIMS_PRIORITY__