+
+/**
+ * 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);
+}