Skip to content

Commit 91d17f6

Browse files
marcinszkudlinskifabiobaltieri
authored andcommitted
kernel: add k_thread_absolute_deadline_set call
k_thread_absolute_deadline_set is simiar to existing k_thread_deadline_set. Diffrence is that k_thread_deadline_set takes a deadline as a time delta from the current time, k_thread_absolute_deadline_set is expecting a timestamp in the same units used by k_cycle_get_32(). This allows to calculate deadlines for several thread and set them in deterministic way, using a common timestamp as a "now" time base. Signed-off-by: Marcin Szkudlinski <[email protected]>
1 parent c2e47bd commit 91d17f6

File tree

2 files changed

+66
-7
lines changed

2 files changed

+66
-7
lines changed

include/zephyr/kernel.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,49 @@ __syscall void k_thread_priority_set(k_tid_t thread, int prio);
959959
*
960960
*/
961961
__syscall void k_thread_deadline_set(k_tid_t thread, int deadline);
962+
963+
/**
964+
* @brief Set deadline expiration time for scheduler
965+
*
966+
* This sets the "deadline" expiration as a timestamp in the same
967+
* units used by k_cycle_get_32(). The scheduler (when deadline scheduling
968+
* is enabled) will choose the next expiring thread when selecting between
969+
* threads at the same static priority. Threads at different priorities
970+
* will be scheduled according to their static priority.
971+
*
972+
* Unlike @ref k_thread_deadline_set which sets a relative timestamp to a
973+
* "now" implicitly determined during its call, this routine sets an
974+
* absolute timestamp that is computed from a timestamp relative to
975+
* an explicit "now" that was determined before this routine is called.
976+
* This allows the caller to specify deadlines for multiple threads
977+
* using a common "now".
978+
*
979+
* @note Deadlines are stored internally using 32 bit unsigned
980+
* integers. The number of cycles between the "first" deadline in the
981+
* scheduler queue and the "last" deadline must be less than 2^31 (i.e
982+
* a signed non-negative quantity). Failure to adhere to this rule
983+
* may result in scheduled threads running in an incorrect deadline
984+
* order.
985+
*
986+
* @note Even if a provided timestamp is in the past, the kernel will
987+
* still schedule threads with deadlines in order from the earliest to
988+
* the latest
989+
*
990+
* @note Despite the API naming, the scheduler makes no guarantees
991+
* the thread WILL be scheduled within that deadline, nor does it take
992+
* extra metadata (like e.g. the "runtime" and "period" parameters in
993+
* Linux sched_setattr()) that allows the kernel to validate the
994+
* scheduling for achievability. Such features could be implemented
995+
* above this call, which is simply input to the priority selection
996+
* logic.
997+
*
998+
* @note You should enable @kconfig_dep{CONFIG_SCHED_DEADLINE} in your project
999+
* configuration.
1000+
*
1001+
* @param thread A thread on which to set the deadline
1002+
* @param deadline A timestamp, in cycle units
1003+
*/
1004+
__syscall void k_thread_absolute_deadline_set(k_tid_t thread, int deadline);
9621005
#endif
9631006

9641007
/**

kernel/sched.c

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -999,13 +999,9 @@ static inline void z_vrfy_k_thread_priority_set(k_tid_t thread, int prio)
999999
#endif /* CONFIG_USERSPACE */
10001000

10011001
#ifdef CONFIG_SCHED_DEADLINE
1002-
void z_impl_k_thread_deadline_set(k_tid_t tid, int deadline)
1002+
void z_impl_k_thread_absolute_deadline_set(k_tid_t tid, int deadline)
10031003
{
1004-
1005-
deadline = CLAMP(deadline, 0, INT_MAX);
1006-
10071004
struct k_thread *thread = tid;
1008-
int32_t newdl = k_cycle_get_32() + deadline;
10091005

10101006
/* The prio_deadline field changes the sorting order, so can't
10111007
* change it while the thread is in the run queue (dlists
@@ -1016,15 +1012,35 @@ void z_impl_k_thread_deadline_set(k_tid_t tid, int deadline)
10161012
K_SPINLOCK(&_sched_spinlock) {
10171013
if (z_is_thread_queued(thread)) {
10181014
dequeue_thread(thread);
1019-
thread->base.prio_deadline = newdl;
1015+
thread->base.prio_deadline = deadline;
10201016
queue_thread(thread);
10211017
} else {
1022-
thread->base.prio_deadline = newdl;
1018+
thread->base.prio_deadline = deadline;
10231019
}
10241020
}
10251021
}
10261022

1023+
void z_impl_k_thread_deadline_set(k_tid_t tid, int deadline)
1024+
{
1025+
1026+
deadline = CLAMP(deadline, 0, INT_MAX);
1027+
1028+
int32_t newdl = k_cycle_get_32() + deadline;
1029+
1030+
z_impl_k_thread_absolute_deadline_set(tid, newdl);
1031+
}
1032+
10271033
#ifdef CONFIG_USERSPACE
1034+
static inline void z_vrfy_k_thread_absolute_deadline_set(k_tid_t tid, int deadline)
1035+
{
1036+
struct k_thread *thread = tid;
1037+
1038+
K_OOPS(K_SYSCALL_OBJ(thread, K_OBJ_THREAD));
1039+
1040+
z_impl_k_thread_absolute_deadline_set((k_tid_t)thread, deadline);
1041+
}
1042+
#include <zephyr/syscalls/k_thread_absolute_deadline_set_mrsh.c>
1043+
10281044
static inline void z_vrfy_k_thread_deadline_set(k_tid_t tid, int deadline)
10291045
{
10301046
struct k_thread *thread = tid;

0 commit comments

Comments
 (0)