kernel/sched: Optimize deadline comparison
Needing to check the current cycle time (which involves a spinlock and register read on most architectures) is wasteful in the scheduler priority predicate, which is a hot path. If we "burn" one bit of precision (and document the rule), we can do the comparison without knowing the current time. 2^31 cycles is still far longer than a live deadline thread in any legitimate realtime app should ever live before being scheduled. Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
parent
912914a915
commit
ef626571b2
2 changed files with 15 additions and 14 deletions
|
@ -718,11 +718,12 @@ __syscall void k_thread_priority_set(k_tid_t thread, int prio);
|
|||
* static priority. Threads at different priorities will be scheduled
|
||||
* according to their static priority.
|
||||
*
|
||||
* @note Deadlines that are negative (i.e. in the past) are still seen
|
||||
* as higher priority than others, even if the thread has "finished"
|
||||
* its work. If you don't want it scheduled anymore, you have to
|
||||
* reset the deadline into the future, block/pend the thread, or
|
||||
* modify its priority with k_thread_priority_set().
|
||||
* @note Deadlines are stored internally using 32 bit unsigned
|
||||
* integers. The number of cycles between the "first" deadline in the
|
||||
* scheduler queue and the "last" deadline must be less than 2^31 (i.e
|
||||
* a signed non-negative quantity). Failure to adhere to this rule
|
||||
* may result in scheduled threads running in an incorrect dealine
|
||||
* order.
|
||||
*
|
||||
* @note Despite the API naming, the scheduler makes no guarantees the
|
||||
* the thread WILL be scheduled within that deadline, nor does it take
|
||||
|
|
|
@ -100,18 +100,18 @@ bool z_is_t1_higher_prio_than_t2(struct k_thread *thread_1,
|
|||
}
|
||||
|
||||
#ifdef CONFIG_SCHED_DEADLINE
|
||||
/* Note that we don't care about wraparound conditions. The
|
||||
* expectation is that the application will have arranged to
|
||||
* block the threads, change their priorities or reset their
|
||||
* deadlines when the job is complete. Letting the deadlines
|
||||
* go negative is fine and in fact prevents aliasing bugs.
|
||||
/* If we assume all deadlines live within the same "half" of
|
||||
* the 32 bit modulus space (this is a documented API rule),
|
||||
* then the latest dealine in the queue minus the earliest is
|
||||
* guaranteed to be (2's complement) non-negative. We can
|
||||
* leverage that to compare the values without having to check
|
||||
* the current time.
|
||||
*/
|
||||
if (thread_1->base.prio == thread_2->base.prio) {
|
||||
int now = (int) k_cycle_get_32();
|
||||
int dt1 = thread_1->base.prio_deadline - now;
|
||||
int dt2 = thread_2->base.prio_deadline - now;
|
||||
int32_t d1 = thread_1->base.prio_deadline;
|
||||
int32_t d2 = thread_2->base.prio_deadline;
|
||||
|
||||
return dt1 < dt2;
|
||||
return (d2 - d1) >= 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue