]> git.saurik.com Git - apple/libpthread.git/blobdiff - kern/kern_policy.c
libpthread-218.1.3.tar.gz
[apple/libpthread.git] / kern / kern_policy.c
index a168bdbcc5b295311b549898b5dc34f569688faf..98e0c61d38f2536576f357c7d6324f88c6b78344 100644 (file)
 #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);
@@ -42,11 +42,25 @@ pthread_qos_class_get_priority(int qos)
                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)) {
@@ -60,8 +74,14 @@ pthread_priority_get_qos_class(pthread_priority_t 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) {
@@ -84,7 +104,26 @@ pthread_priority_from_class_index(int 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;
@@ -93,21 +132,51 @@ qos_get_class_index(int qos){
                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);
 }