From f543214a40982d1c32aa393c3cfb93c3e6749dac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E8=B5=9B?= Date: Thu, 18 Apr 2024 12:06:56 +0800 Subject: [PATCH] lib/tnschedprio: Support time slice MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 刘赛 --- include/uk/plat/lcpu.h | 2 + lib/tnschedprio/Config.uk | 10 +++++ lib/tnschedprio/exportsyms.uk | 1 + lib/tnschedprio/schedprio.c | 83 +++++++++++++++++++++++++++++++++++ lib/tnsystick/tnsystick.c | 5 ++- lib/uksched/Config.uk | 3 ++ lib/uksched/exportsyms.uk | 1 + lib/uksched/sched.c | 7 +++ 8 files changed, 110 insertions(+), 2 deletions(-) diff --git a/include/uk/plat/lcpu.h b/include/uk/plat/lcpu.h index bae0f1f5..1ccfec19 100644 --- a/include/uk/plat/lcpu.h +++ b/include/uk/plat/lcpu.h @@ -261,6 +261,8 @@ int ukplat_lcpu_wakeup(const __lcpuidx lcpuidx[], unsigned int *num); var_name[lcpu_idx][idx] #define ukplat_per_lcpu_array_current(var_name, idx) \ ukplat_per_lcpu_array(var_name, ukplat_lcpu_idx(), idx) +#define ukplat_per_lcpu_var_to_idx(var_name, var) \ + ((var)-&(var_name[0])) #ifdef __cplusplus } diff --git a/lib/tnschedprio/Config.uk b/lib/tnschedprio/Config.uk index 298d24ee..758c0154 100644 --- a/lib/tnschedprio/Config.uk +++ b/lib/tnschedprio/Config.uk @@ -21,4 +21,14 @@ if LIBTNSCHEDPRIO depends on LIBUKSCHED_RUNQ_LIST bool "Use double linked list based algorithm for run queue" endchoice + + config LIBTNSCHEDPRIO_ENABLE_TIMESLICING + depends on LIBUKSCHED_ENABLE_TICKANNOUNCE + bool "Enable time slice" + default n + + config LIBTNSCHEDPRIO_TIMESLICE_SIZE + depends on LIBTNSCHEDPRIO_ENABLE_TIMESLICING + int "Time slice size" + default 0 endif diff --git a/lib/tnschedprio/exportsyms.uk b/lib/tnschedprio/exportsyms.uk index c99178f7..1cf4ee4d 100644 --- a/lib/tnschedprio/exportsyms.uk +++ b/lib/tnschedprio/exportsyms.uk @@ -1 +1,2 @@ tn_schedprio_create +schedprio_tick_announce diff --git a/lib/tnschedprio/schedprio.c b/lib/tnschedprio/schedprio.c index 6e7333b0..fa6aaaeb 100644 --- a/lib/tnschedprio/schedprio.c +++ b/lib/tnschedprio/schedprio.c @@ -19,8 +19,67 @@ #include #include #include +#include #include "schedprio.h" +#ifdef CONFIG_LIBTNSCHEDPRIO_ENABLE_TIMESLICING +UKPLAT_PER_LCPU_DEFINE(struct timer, __tn_sched_timeslice_timer); +UKPLAT_PER_LCPU_DEFINE(bool, __tn_sched_timeslice_expired); +UKPLAT_PER_LCPU_DEFINE(bool, __tn_sched_timeslice_run); +static int slice_ticks = CONFIG_LIBTNSCHEDPRIO_TIMESLICE_SIZE; + +static inline int slice_time(struct uk_thread *t) +{ + int ret = slice_ticks; + + return ret; +} + +bool sliceable(struct uk_thread *t) +{ + bool ret = uk_sched_idle_thread(t->sched, 0) != t + && uk_thread_is_runnable(t) + && slice_time(t) != 0; + + return ret; +} + +void slice_timeout(struct timer *t) +{ + int cpu = ukplat_per_lcpu_var_to_idx(__tn_sched_timeslice_timer, t); + + __tn_sched_timeslice_expired[cpu] = true; +} + +void reset_timeslice(struct uk_thread *t) +{ + int cpu = ukplat_lcpu_id(); + + if (__tn_sched_timeslice_run[cpu]) { + tn_timer_delete(&__tn_sched_timeslice_timer[cpu]); + __tn_sched_timeslice_run[cpu] = false; + } + __tn_sched_timeslice_expired[cpu] = false; + if (sliceable(t)) { + tn_timer_init(&__tn_sched_timeslice_timer[cpu], + slice_time(t), *slice_timeout, + &__tn_sched_timeslice_timer[cpu], + TN_TIMER_FLAG_ONE_SHOT); + tn_timer_start(&__tn_sched_timeslice_timer[cpu]); + __tn_sched_timeslice_run[cpu] = true; + } +} + +void schedprio_tick_announce(void) +{ + int cpu = ukplat_lcpu_id(); + struct uk_thread *curr = uk_thread_current(); + + if (__tn_sched_timeslice_expired[cpu] && sliceable(curr)) + reset_timeslice(curr); +} +#endif /* CONFIG_LIBTNSCHEDPRIO_ENABLE_TIMESLICING */ + static inline void schedprio_schedule(struct schedprio *c, bool yield) { struct uk_thread *prev, *next, *thread, *tmp; @@ -87,6 +146,27 @@ static inline void schedprio_schedule(struct schedprio *c, bool yield) switch_thread: if (next != prev) { +#ifdef CONFIG_LIBTNSCHEDPRIO_ENABLE_TIMESLICING + int cpu = ukplat_lcpu_id(); + + if (uk_sched_idle_thread(next->sched, 0) == next) { + if (__tn_sched_timeslice_run[cpu]) { + tn_timer_delete(&__tn_sched_timeslice_timer[cpu]); + __tn_sched_timeslice_run[cpu] = false; + } + } else { + if (__tn_sched_timeslice_run[cpu]) { + tn_timer_delete(&__tn_sched_timeslice_timer[cpu]); + __tn_sched_timeslice_run[cpu] = false; + } + tn_timer_init(&__tn_sched_timeslice_timer[cpu], + slice_time(next), *slice_timeout, + &__tn_sched_timeslice_timer[cpu], + TN_TIMER_FLAG_ONE_SHOT); + tn_timer_start(&__tn_sched_timeslice_timer[cpu]); + __tn_sched_timeslice_run[cpu] = true; + } +#endif /* CONFIG_LIBTNSCHEDPRIO_ENABLE_TIMESLICING */ /* * Schedule idle thread that will halt the CPU * We select the idle thread only if we do not @@ -245,6 +325,9 @@ static int schedprio_start(struct uk_sched *s __maybe_unused, */ ukplat_lcpu_enable_irq(); +#ifdef CONFIG_LIBTNSCHEDPRIO_ENABLE_TIMESLICING + reset_timeslice(main_thread); +#endif /* CONFIG_LIBTNSCHEDPRIO_ENABLE_TIMESLICING */ return 0; } diff --git a/lib/tnsystick/tnsystick.c b/lib/tnsystick/tnsystick.c index 80cf4424..c41ea4e3 100644 --- a/lib/tnsystick/tnsystick.c +++ b/lib/tnsystick/tnsystick.c @@ -101,8 +101,9 @@ int sys_timer_irq_handler(void *arg __unused) sysclock.ops->set_next(tot_counts_per_tick, 0); #endif /* CONFIG_LIBTNSYSTICK_TICKLESS */ tn_timer_announce(); - /* 3、todo :schedprio to check timeout threads */ - +#ifdef CONFIG_LIBUKSCHED_ENABLE_TICKANNOUNCE + uk_sched_tick_announce(); +#endif /* CONFIG_LIBUKSCHED_ENABLE_TICKANNOUNCE */ /* 4、set next time-base irq */ #ifdef CONFIG_LIBTNSYSTICK_TICKLESS systick_t timeout; diff --git a/lib/uksched/Config.uk b/lib/uksched/Config.uk index 1ce1f691..1623e719 100644 --- a/lib/uksched/Config.uk +++ b/lib/uksched/Config.uk @@ -60,4 +60,7 @@ if LIBUKSCHED config LIBUKSCHED_TEST bool "Enable unit tests" default n + config LIBUKSCHED_ENABLE_TICKANNOUNCE + bool "Enable tick announce" + default n endif diff --git a/lib/uksched/exportsyms.uk b/lib/uksched/exportsyms.uk index 7874cc65..dd424bda 100644 --- a/lib/uksched/exportsyms.uk +++ b/lib/uksched/exportsyms.uk @@ -13,6 +13,7 @@ uk_sched_thread_exit2 uk_sched_dumpk_threads uk_sched_thread_gc uk_sched_thread_set_priority +uk_sched_tick_announce uk_thread_init_bare uk_thread_init_bare_fn0 uk_thread_init_bare_fn1 diff --git a/lib/uksched/sched.c b/lib/uksched/sched.c index 94fee450..22b58501 100644 --- a/lib/uksched/sched.c +++ b/lib/uksched/sched.c @@ -460,3 +460,10 @@ void uk_sched_thread_set_priority(struct uk_thread *thread, int32_t priority) thread->sched->thread_set_prio(thread->sched, thread, priority); } #endif + +#ifdef CONFIG_LIBUKSCHED_ENABLE_TICKANNOUNCE +void uk_sched_tick_announce(void) +{ + schedprio_tick_announce(); +} +#endif /* CONFIG_LIBUKSCHED_ENABLE_TICKANNOUNCE */ -- Gitee