kernel: New timeout implementation

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>
This commit is contained in:
Andy Ross 2018-09-27 16:50:00 -07:00 committed by Anas Nashif
commit 987c0e5fc1
11 changed files with 315 additions and 637 deletions

View file

@ -1330,9 +1330,8 @@ struct k_timer {
#define _K_TIMER_INITIALIZER(obj, expiry, stop) \
{ \
.timeout.delta_ticks_from_prev = _INACTIVE, \
.timeout.thread = NULL, \
.timeout.func = _timer_expiration_handler, \
.timeout.dticks = _INACTIVE, \
.timeout.fn = _timer_expiration_handler, \
.wait_q = _WAIT_Q_INIT(&obj.wait_q), \
.expiry_fn = expiry, \
.stop_fn = stop, \
@ -1608,7 +1607,16 @@ __syscall u32_t k_uptime_get_32(void);
*
* @return Elapsed time.
*/
extern s64_t k_uptime_delta(s64_t *reftime);
static inline s64_t k_uptime_delta(s64_t *reftime)
{
s64_t uptime, delta;
uptime = k_uptime_get();
delta = uptime - *reftime;
*reftime = uptime;
return delta;
}
/**
* @brief Get elapsed time (32-bit version).
@ -1626,7 +1634,10 @@ extern s64_t k_uptime_delta(s64_t *reftime);
*
* @return Elapsed time.
*/
extern u32_t k_uptime_delta_32(s64_t *reftime);
static inline u32_t k_uptime_delta_32(s64_t *reftime)
{
return (u32_t)k_uptime_delta(reftime);
}
/**
* @brief Read the hardware clock.