]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/kern/sched_prim.c
xnu-1504.9.17.tar.gz
[apple/xnu.git] / osfmk / kern / sched_prim.c
index 78b43fa83b240e4d911e0d01d39143183e4038b4..2ed0f12e7371067fe5a52ae2f96ca82867346afb 100644 (file)
@@ -466,7 +466,6 @@ thread_unblock(
                        if (processor != current_processor())
                                machine_signal_idle(processor);
                }
-
                result = TRUE;
        }
 
@@ -1258,12 +1257,8 @@ thread_select(
                        }
                        else {
                                enqueue_head(&processor->processor_meta->idle_queue, (queue_entry_t)processor);
-
-                               if (thread->sched_pri < BASEPRI_RTQUEUES) {
-                                       pset_unlock(pset);
-
-                                       return (processor->idle_thread);
-                               }
+                               pset_unlock(pset);
+                               return (processor->idle_thread);
                        }
                }
 
@@ -2263,38 +2258,32 @@ choose_processor(
 {
        processor_set_t         nset, cset = pset;
        processor_meta_t        pmeta = PROCESSOR_META_NULL;
-
+       processor_t             mprocessor;
+       
        /*
         *      Prefer the hinted processor, when appropriate.
         */
-       if (processor != PROCESSOR_NULL) {
-               processor_t                     mprocessor;
 
+       if (processor != PROCESSOR_NULL) {
                if (processor->processor_meta != PROCESSOR_META_NULL)
                        processor = processor->processor_meta->primary;
+       }
 
-               mprocessor = machine_choose_processor(pset, processor);
-               if (mprocessor != PROCESSOR_NULL)
-                       processor = mprocessor;
+       mprocessor = machine_choose_processor(pset, processor);
+       if (mprocessor != PROCESSOR_NULL)
+               processor = mprocessor;
 
-               if (processor->processor_set != pset || processor->state == PROCESSOR_INACTIVE ||
-                               processor->state == PROCESSOR_SHUTDOWN || processor->state == PROCESSOR_OFF_LINE)
+       if (processor != PROCESSOR_NULL) {
+               if (processor->processor_set != pset ||
+                   processor->state == PROCESSOR_INACTIVE ||
+                   processor->state == PROCESSOR_SHUTDOWN ||
+                   processor->state == PROCESSOR_OFF_LINE)
                        processor = PROCESSOR_NULL;
                else
-               if (processor->state == PROCESSOR_IDLE)
-                       return (processor);
-       }
-       else {
-               processor = machine_choose_processor(pset, processor);
-
-               if (processor != PROCESSOR_NULL) {
-                       if (processor->processor_set != pset || processor->state == PROCESSOR_INACTIVE ||
-                                       processor->state == PROCESSOR_SHUTDOWN || processor->state == PROCESSOR_OFF_LINE)
-                               processor = PROCESSOR_NULL;
-                       else
-                               if (processor->state == PROCESSOR_IDLE)
-                                       return (processor);
-               }
+                       if (processor->state == PROCESSOR_IDLE ||
+                           ((thread->sched_pri >= BASEPRI_RTQUEUES) &&
+                           (processor->current_pri < BASEPRI_RTQUEUES)))
+                               return (processor);
        }
 
        /*
@@ -2309,27 +2298,67 @@ choose_processor(
                        return ((processor_t)queue_first(&cset->idle_queue));
 
                if (thread->sched_pri >= BASEPRI_RTQUEUES) {
-                       /*
-                        *      For an RT thread, iterate through active processors, first fit.
-                        */
+                       integer_t lowest_priority = MAXPRI + 1;
+                       integer_t lowest_unpaired = MAXPRI + 1;
+                       uint64_t  furthest_deadline = 1;
+                       processor_t lp_processor = PROCESSOR_NULL;
+                       processor_t lp_unpaired = PROCESSOR_NULL;
+                       processor_t fd_processor = PROCESSOR_NULL;
+
+                       lp_processor = cset->low_pri;
+                       /* Consider hinted processor */
+                       if (lp_processor != PROCESSOR_NULL &&
+                       ((lp_processor->processor_meta == PROCESSOR_META_NULL) ||
+                       ((lp_processor == lp_processor->processor_meta->primary) &&
+                           !queue_empty(&lp_processor->processor_meta->idle_queue))) &&
+                           lp_processor->state != PROCESSOR_INACTIVE &&
+                           lp_processor->state != PROCESSOR_SHUTDOWN &&
+                           lp_processor->state != PROCESSOR_OFF_LINE &&
+                           (lp_processor->current_pri < thread->sched_pri))
+                               return lp_processor;
+
                        processor = (processor_t)queue_first(&cset->active_queue);
                        while (!queue_end(&cset->active_queue, (queue_entry_t)processor)) {
-                               if (thread->sched_pri > processor->current_pri ||
-                                               thread->realtime.deadline < processor->deadline)
-                                       return (processor);
+                               /* Discover the processor executing the
+                                * thread with the lowest priority within
+                                * this pset, or the one with the furthest
+                                * deadline
+                                */
+                               integer_t cpri = processor->current_pri;
+                               if (cpri < lowest_priority) {
+                                       lowest_priority = cpri;
+                                       lp_processor = processor;
+                               }
 
-                               if (pmeta == PROCESSOR_META_NULL) {
-                                       if (processor->processor_meta != PROCESSOR_META_NULL &&
-                                                               !queue_empty(&processor->processor_meta->idle_queue))
-                                               pmeta = processor->processor_meta;
+                               if ((cpri >= BASEPRI_RTQUEUES) && (processor->deadline > furthest_deadline)) {
+                                       furthest_deadline = processor->deadline;
+                                       fd_processor = processor;
                                }
 
+
+                               if (processor->processor_meta != PROCESSOR_META_NULL &&
+                                   !queue_empty(&processor->processor_meta->idle_queue)) {
+                                       if (cpri < lowest_unpaired) {
+                                               lowest_unpaired = cpri;
+                                               lp_unpaired = processor;
+                                               pmeta = processor->processor_meta;
+                                       }
+                                       else
+                                               if (pmeta == PROCESSOR_META_NULL)
+                                                       pmeta = processor->processor_meta;
+                               }
                                processor = (processor_t)queue_next((queue_entry_t)processor);
                        }
 
+                       if (thread->sched_pri > lowest_unpaired)
+                               return lp_unpaired;
+
                        if (pmeta != PROCESSOR_META_NULL)
                                return ((processor_t)queue_first(&pmeta->idle_queue));
-
+                       if (thread->sched_pri > lowest_priority)
+                               return lp_processor;
+                       if (thread->realtime.deadline < furthest_deadline)
+                               return fd_processor;
                        processor = PROCESSOR_NULL;
                }
                else {
@@ -2358,10 +2387,9 @@ choose_processor(
                                if (processor != PROCESSOR_NULL)
                                        enqueue_tail(&cset->active_queue, (queue_entry_t)processor);
                        }
-
                        if (processor != PROCESSOR_NULL && pmeta == PROCESSOR_META_NULL) {
                                if (processor->processor_meta != PROCESSOR_META_NULL &&
-                                                                                       !queue_empty(&processor->processor_meta->idle_queue))
+                                   !queue_empty(&processor->processor_meta->idle_queue))
                                        pmeta = processor->processor_meta;
                        }
                }
@@ -2491,21 +2519,7 @@ thread_setrun(
                        processor = thread->last_processor;
                        pset = processor->processor_set;
                        pset_lock(pset);
-
-                       /*
-                        *      Choose a different processor in certain cases.
-                        */
-                       if (thread->sched_pri >= BASEPRI_RTQUEUES) {
-                               /*
-                                *      If the processor is executing an RT thread with
-                                *      an earlier deadline, choose another.
-                                */
-                               if (thread->sched_pri <= processor->current_pri ||
-                                               thread->realtime.deadline >= processor->deadline)
-                                       processor = choose_processor(pset, PROCESSOR_NULL, thread);
-                       }
-                       else
-                               processor = choose_processor(pset, processor, thread);
+                       processor = choose_processor(pset, processor, thread);
                }
                else {
                        /*