mirror of
https://github.com/zephyrproject-rtos/zephyr
synced 2025-08-26 12:56:10 +00:00
Now that the API has been fixed up, replace the existing timeout queue with a much smaller version. The basic algorithm is unchanged: timeouts are stored in a sorted dlist with each node nolding a delta time from the previous node in the list; the announce call just walks this list pulling off the heads as needed. Advantages: * Properly spinlocked and SMP-aware. The earlier timer implementation relied on only CPU 0 doing timeout work, and on an irq_lock() being taken before entry (something that was violated in a few spots). Now any CPU can wake up for an event (or all of them) and everything works correctly. * The *_thread_timeout() API is now expressible as a clean wrapping (just one liners) around the lower-level interface based on function pointer callbacks. As a result the timeout objects no longer need to store backpointers to the thread and wait_q and have shrunk by 33%. * MUCH smaller, to the tune of hundreds of lines of code removed. * Future proof, in that all operations on the queue are now fronted by just two entry points (_add_timeout() and z_clock_announce()) which can easily be augmented with fancier data structures. Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
70 lines
1.6 KiB
C
70 lines
1.6 KiB
C
#ifndef ZEPHYR_LEGACY_SET_TIME_H__
|
|
#define ZEPHYR_LEGACY_SET_TIME_H__
|
|
|
|
/* Stub implementation of z_clock_set_timeout() and z_clock_elapsed()
|
|
* in terms of the original APIs. Used by older timer drivers.
|
|
* Should be replaced.
|
|
*
|
|
* Yes, this "header" includes function definitions and must be
|
|
* included only once in a single compilation.
|
|
*/
|
|
|
|
#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 u64_t z_clock_uptime(void);
|
|
|
|
void z_clock_set_timeout(s32_t ticks, bool idle)
|
|
{
|
|
#ifdef CONFIG_TICKLESS_KERNEL
|
|
if (idle) {
|
|
_timer_idle_enter(ticks);
|
|
} else {
|
|
_set_time(ticks == K_FOREVER ? 0 : ticks);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/* The old driver "now" API would return a full uptime value. The new
|
|
* one only requires the driver to track ticks since the last announce
|
|
* call. Implement the new call in terms of the old one on legacy
|
|
* drivers by keeping (yet another) uptime value locally.
|
|
*/
|
|
static u32_t driver_uptime;
|
|
|
|
u32_t z_clock_elapsed(void)
|
|
{
|
|
#ifdef TICKLESS_KERNEL
|
|
return (u32_t)(z_clock_uptime() - driver_uptime);
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
static void wrapped_announce(s32_t ticks)
|
|
{
|
|
driver_uptime += ticks;
|
|
z_clock_announce(ticks);
|
|
}
|
|
|
|
#define z_clock_announce(t) wrapped_announce(t)
|
|
|
|
#define _sys_clock_always_on (0)
|
|
|
|
static inline void z_tick_set(s64_t val)
|
|
{
|
|
/* noop with current kernel code, use z_clock_announce() */
|
|
ARG_UNUSED(val);
|
|
}
|
|
|
|
#endif /* ZEPHYR_LEGACY_SET_TIME_H__ */
|