X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/1c79356b52d46aa6b508fb032f5ae709b1f2897b..ac5ea4a98a4e1d34a076095ea1eaa87e43d1f335:/osfmk/kern/priority.c?ds=inline diff --git a/osfmk/kern/priority.c b/osfmk/kern/priority.c index d88ade25d..084e8fe2c 100644 --- a/osfmk/kern/priority.c +++ b/osfmk/kern/priority.c @@ -69,154 +69,90 @@ #include #include #include -#include -#include /*** ??? fix so this can be removed ***/ -/*** ??? Should this file be MK SP-specific? Or is it more general purpose? ***/ - - - -/* - * USAGE_THRESHOLD is the amount by which usage must change to - * cause a priority shift that moves a thread between run queues. - */ - -#ifdef PRI_SHIFT_2 -#if PRI_SHIFT_2 > 0 -#define USAGE_THRESHOLD (((1 << PRI_SHIFT) + (1 << PRI_SHIFT_2)) << (2 + SCHED_SHIFT)) -#else /* PRI_SHIFT_2 > 0 */ -#define USAGE_THRESHOLD (((1 << PRI_SHIFT) - (1 << -(PRI_SHIFT_2))) << (2 + SCHED_SHIFT)) -#endif /* PRI_SHIFT_2 > 0 */ -#else /* PRI_SHIFT_2 */ -#define USAGE_THRESHOLD (1 << (PRI_SHIFT + 2 + SCHED_SHIFT)) -#endif /* PRI_SHIFT_2 */ /* - * thread_quantum_update: + * thread_quantum_expire: * * Recalculate the quantum and priority for a thread. - * The number of ticks that has elapsed since we were last called - * is passed as "nticks." */ void -thread_quantum_update( - register int mycpu, - register thread_t thread, - int nticks, - int state) +thread_quantum_expire( + timer_call_param_t p0, + timer_call_param_t p1) { - register int quantum; - register processor_t myprocessor; - register processor_set_t pset; + register processor_t myprocessor = p0; + register thread_t thread = p1; spl_t s; - myprocessor = cpu_to_processor(mycpu); - pset = myprocessor->processor_set; + s = splsched(); + thread_lock(thread); /* - * Account for thread's utilization of these ticks. - * This assumes that there is *always* a current thread. - * When the processor is idle, it should be the idle thread. + * Check for fail-safe trip. */ + if (!(thread->sched_mode & TH_MODE_TIMESHARE)) { + extern uint64_t max_unsafe_computation; + uint64_t new_computation; - /* - * Update set_quantum and calculate the current quantum. - */ - pset->set_quantum = pset->machine_quantum[ - (pset->runq.count > pset->processor_count) ? - pset->processor_count : pset->runq.count]; + new_computation = myprocessor->quantum_end; + new_computation -= thread->computation_epoch; + if (new_computation + thread->computation_metered > + max_unsafe_computation) { + extern uint32_t sched_safe_duration; - if (myprocessor->runq.count != 0) - quantum = min_quantum; - else - quantum = pset->set_quantum; - - /* - * Now recompute the priority of the thread if appropriate. - */ - - { - s = splsched(); - thread_lock(thread); + if (thread->sched_mode & TH_MODE_REALTIME) { + thread->priority = DEPRESSPRI; - if (!(thread->policy & (POLICY_TIMESHARE|POLICY_RR|POLICY_FIFO))) { - thread_unlock(thread); - splx(s); - return; - } + thread->safe_mode |= TH_MODE_REALTIME; + thread->sched_mode &= ~TH_MODE_REALTIME; + } - if (thread->state&TH_IDLE) { - /* Don't try to time-slice idle threads */ - myprocessor->first_quantum = TRUE; - if (thread->sched_stamp != sched_tick) - update_priority(thread); - thread_unlock(thread); - splx(s); - ast_check(); - return; + thread->safe_release = sched_tick + sched_safe_duration; + thread->sched_mode |= (TH_MODE_FAILSAFE|TH_MODE_TIMESHARE); + thread->sched_mode &= ~TH_MODE_PREEMPT; } + } + + /* + * Recompute scheduled priority if appropriate. + */ + if (thread->sched_stamp != sched_tick) + update_priority(thread); + else + if (thread->sched_mode & TH_MODE_TIMESHARE) { + thread_timer_delta(thread); + thread->sched_usage += thread->sched_delta; + thread->sched_delta = 0; - myprocessor->quantum -= nticks; /* - * Runtime quantum adjustment. Use quantum_adj_index - * to avoid synchronizing quantum expirations. + * Adjust the scheduled priority if + * the thread has not been promoted + * and is not depressed. */ - if ( quantum != myprocessor->last_quantum && - pset->processor_count > 1 ) { - myprocessor->last_quantum = quantum; - simple_lock(&pset->quantum_adj_lock); - quantum = min_quantum + (pset->quantum_adj_index * - (quantum - min_quantum)) / - (pset->processor_count - 1); - if (++(pset->quantum_adj_index) >= pset->processor_count) - pset->quantum_adj_index = 0; - simple_unlock(&pset->quantum_adj_lock); - } - if (myprocessor->quantum <= 0) { - if (thread->sched_stamp != sched_tick) - update_priority(thread); - else - if ( thread->policy == POLICY_TIMESHARE && - thread->depress_priority < 0 ) { - thread_timer_delta(thread); - thread->sched_usage += thread->sched_delta; - thread->sched_delta = 0; - compute_my_priority(thread); - } + if ( !(thread->sched_mode & TH_MODE_PROMOTED) && + !(thread->sched_mode & TH_MODE_ISDEPRESSED) ) + compute_my_priority(thread); + } - /* - * This quantum is up, give this thread another. - */ - myprocessor->first_quantum = FALSE; - if (thread->policy == POLICY_TIMESHARE) - myprocessor->quantum += quantum; - else - myprocessor->quantum += min_quantum; - } - /* - * Recompute priority if appropriate. - */ - else { - if (thread->sched_stamp != sched_tick) - update_priority(thread); - else - if ( thread->policy == POLICY_TIMESHARE && - thread->depress_priority < 0 ) { - thread_timer_delta(thread); - if (thread->sched_delta >= USAGE_THRESHOLD) { - thread->sched_usage += thread->sched_delta; - thread->sched_delta = 0; - compute_my_priority(thread); - } - } - } + /* + * This quantum is up, give this thread another. + */ + if (first_quantum(myprocessor)) + myprocessor->slice_quanta--; - thread_unlock(thread); - splx(s); + thread->current_quantum = (thread->sched_mode & TH_MODE_REALTIME)? + thread->realtime.computation: std_quantum; + myprocessor->quantum_end += thread->current_quantum; + timer_call_enter1(&myprocessor->quantum_timer, + thread, myprocessor->quantum_end); - /* - * Check for and schedule ast if needed. - */ - ast_check(); - } + thread_unlock(thread); + + /* + * Check for and schedule ast if needed. + */ + ast_check(myprocessor); + + splx(s); }