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

@ -84,7 +84,7 @@ static inline int _is_thread_prevented_from_running(struct k_thread *thread)
static inline bool _is_thread_timeout_active(struct k_thread *thread)
{
#ifdef CONFIG_SYS_CLOCK_EXISTS
return thread->base.timeout.delta_ticks_from_prev != _INACTIVE;
return thread->base.timeout.dticks != _INACTIVE;
#else
return false;
#endif
@ -266,7 +266,7 @@ static ALWAYS_INLINE void _sched_unlock_no_reschedule(void)
static ALWAYS_INLINE bool _is_thread_timeout_expired(struct k_thread *thread)
{
#ifdef CONFIG_SYS_CLOCK_EXISTS
return thread->base.timeout.delta_ticks_from_prev == _EXPIRED;
return thread->base.timeout.dticks == _EXPIRED;
#else
return 0;
#endif