diff --git a/include/kernel.h b/include/kernel.h index 9dcd0a0b491..36a6c151a1d 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -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 diff --git a/kernel/sched.c b/kernel/sched.c index fa825a22174..bc725814559 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -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