timer: Clean up hairy tickless APIs
The tickless driver had a bunch of "hairy" APIs which forced the timer drivers to do needless low-level accounting for the benefit of the kernel, all of which then proceeded to implement them via cut and paste. Specifically the "program_time" calls forced the driver to expose to the kernel exactly when the next interrupt was due and how much time had elapsed, in a parallel API to the existing "what time is it" and "announce a tick" interrupts that carry the same information. Remove these from the kernel, replacing them with synthesized logic written in terms of the simpler APIs. In some cases there will be a performance impact due to the use of the 64 bit uptime call, but that will go away soon. Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
This commit is contained in:
parent
1a1a9539ea
commit
722a888ef7
6 changed files with 34 additions and 40 deletions
|
@ -8,16 +8,18 @@
|
|||
* included only once in a single compilation.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef CONFIG_TICKLESS_KERNEL
|
||||
void _set_time(u32_t time);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TICKLESS_IDLE
|
||||
void _timer_idle_enter(s32_t ticks);
|
||||
void z_clock_idle_exit(void);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TICKLESS_KERNEL
|
||||
void _set_time(u32_t time);
|
||||
extern u32_t _get_program_time(void);
|
||||
extern u32_t _get_remaining_program_time(void);
|
||||
extern u32_t _get_elapsed_program_time(void);
|
||||
#endif
|
||||
|
||||
extern void z_clock_set_timeout(s32_t ticks, bool idle)
|
||||
{
|
||||
#ifdef CONFIG_TICKLESS_KERNEL
|
||||
|
|
|
@ -109,12 +109,6 @@ extern void z_clock_announce(s32_t ticks);
|
|||
*/
|
||||
extern u64_t z_clock_uptime(void);
|
||||
|
||||
#ifdef CONFIG_TICKLESS_KERNEL
|
||||
extern u32_t _get_program_time(void);
|
||||
extern u32_t _get_remaining_program_time(void);
|
||||
extern u32_t _get_elapsed_program_time(void);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include <power.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
extern u64_t z_last_tick_announced;
|
||||
|
||||
#if defined(CONFIG_TICKLESS_IDLE)
|
||||
/*
|
||||
* Idle time must be this value or higher for timer to go into tickless idle
|
||||
|
@ -72,7 +74,7 @@ static void sys_power_save_idle(s32_t ticks)
|
|||
{
|
||||
#ifdef CONFIG_TICKLESS_KERNEL
|
||||
if (ticks != K_FOREVER) {
|
||||
ticks -= _get_elapsed_program_time();
|
||||
ticks -= (int)(z_clock_uptime() - z_last_tick_announced);
|
||||
if (!ticks) {
|
||||
/*
|
||||
* Timer has expired or about to expire
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern u64_t z_last_tick_announced;
|
||||
|
||||
/* initialize the timeouts part of k_thread when enabled in the kernel */
|
||||
|
||||
static inline void _init_timeout(struct _timeout *t, _timeout_func_t func)
|
||||
|
@ -172,6 +174,16 @@ static inline void _dump_timeout_q(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
/* find the closest deadline in the timeout queue */
|
||||
|
||||
static inline s32_t _get_next_timeout_expiry(void)
|
||||
{
|
||||
struct _timeout *t = (struct _timeout *)
|
||||
sys_dlist_peek_head(&_timeout_q);
|
||||
|
||||
return t ? t->delta_ticks_from_prev : K_FOREVER;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add timeout to timeout queue. Record waiting thread and wait queue if any.
|
||||
*
|
||||
|
@ -229,11 +241,9 @@ static inline void _add_timeout(struct k_thread *thread,
|
|||
* This is like adding this timout back in history.
|
||||
*/
|
||||
u32_t adjusted_timeout;
|
||||
u32_t program_time = _get_program_time();
|
||||
|
||||
if (program_time > 0) {
|
||||
*delta += _get_elapsed_program_time();
|
||||
}
|
||||
*delta += (int)(z_clock_uptime() - z_last_tick_announced);
|
||||
|
||||
adjusted_timeout = *delta;
|
||||
#endif
|
||||
SYS_DLIST_FOR_EACH_CONTAINER(&_timeout_q, in_q, node) {
|
||||
|
@ -255,7 +265,7 @@ inserted:
|
|||
_dump_timeout_q();
|
||||
|
||||
#ifdef CONFIG_TICKLESS_KERNEL
|
||||
if (!program_time || (adjusted_timeout < program_time)) {
|
||||
if (adjusted_timeout < _get_next_timeout_expiry()) {
|
||||
z_clock_set_timeout(adjusted_timeout, false);
|
||||
}
|
||||
#endif
|
||||
|
@ -276,16 +286,6 @@ static inline void _add_thread_timeout(struct k_thread *thread,
|
|||
_add_timeout(thread, &thread->base.timeout, wait_q, timeout_in_ticks);
|
||||
}
|
||||
|
||||
/* find the closest deadline in the timeout queue */
|
||||
|
||||
static inline s32_t _get_next_timeout_expiry(void)
|
||||
{
|
||||
struct _timeout *t = (struct _timeout *)
|
||||
sys_dlist_peek_head(&_timeout_q);
|
||||
|
||||
return t ? t->delta_ticks_from_prev : K_FOREVER;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -648,17 +648,11 @@ void _update_time_slice_before_swap(void)
|
|||
return;
|
||||
}
|
||||
|
||||
u32_t remaining = _get_remaining_program_time();
|
||||
|
||||
if (!remaining || (_time_slice_duration < remaining)) {
|
||||
z_clock_set_timeout(_time_slice_duration, false);
|
||||
} else {
|
||||
/* Account previous elapsed time and reprogram
|
||||
* timer with remaining time
|
||||
*/
|
||||
z_clock_set_timeout(remaining, false);
|
||||
}
|
||||
int elapsed = (int)(z_clock_uptime() - z_last_tick_announced);
|
||||
int next_timeout = _get_next_timeout_expiry() - elapsed;
|
||||
int t = min(_time_slice_duration, next_timeout);
|
||||
|
||||
z_clock_set_timeout(t, false);
|
||||
#endif
|
||||
/* Restart time slice count at new thread switch */
|
||||
_time_slice_elapsed = 0;
|
||||
|
|
|
@ -36,6 +36,8 @@ int z_clock_hw_cycles_per_sec;
|
|||
*/
|
||||
static volatile u64_t tick_count;
|
||||
|
||||
u64_t z_last_tick_announced;
|
||||
|
||||
#ifdef CONFIG_TICKLESS_KERNEL
|
||||
/*
|
||||
* If this flag is set, system clock will run continuously even if
|
||||
|
@ -291,6 +293,8 @@ static void handle_time_slicing(s32_t ticks)
|
|||
*/
|
||||
void z_clock_announce(s32_t ticks)
|
||||
{
|
||||
z_last_tick_announced += ticks;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* sys_clock timekeeping happens only on the main CPU */
|
||||
if (_arch_curr_cpu()->id) {
|
||||
|
@ -319,9 +323,7 @@ void z_clock_announce(s32_t ticks)
|
|||
next_to = !next_to || (next_ts
|
||||
&& next_to) > next_ts ? next_ts : next_to;
|
||||
|
||||
u32_t remaining = _get_remaining_program_time();
|
||||
|
||||
if ((!remaining && next_to) || (next_to < remaining)) {
|
||||
if (next_to) {
|
||||
/* Clears current program if next_to = 0 and remaining > 0 */
|
||||
int dt = next_to ? next_to : (_sys_clock_always_on ? INT_MAX : K_FOREVER);
|
||||
z_clock_set_timeout(dt, false);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue