kernel: add flag that tells the system is handling timeouts

This limits the execution contexts that will go over the loop in
_unpend_first_thread() to only ISRs of very high priority that are
preempting the system clock timer ISR, and only during the time it is
handling timeouts.

Change-Id: Iaf0500d28a2de5e077c9cf9861a5a70244127d58
Signed-off-by: Benjamin Walsh <benjamin.walsh@windriver.com>
This commit is contained in:
Benjamin Walsh 2016-12-19 13:55:17 -05:00 committed by Anas Nashif
commit eec37e6752
2 changed files with 11 additions and 2 deletions

View file

@ -418,11 +418,13 @@ static inline struct k_thread *_peek_first_pending_thread(_wait_q_t *wait_q)
static inline struct k_thread *_get_thread_to_unpend(_wait_q_t *wait_q)
{
#ifdef CONFIG_SYS_CLOCK_EXISTS
if (_is_in_isr()) {
/* skip threads that have an expired timeout */
extern volatile int _handling_timeouts;
if (_handling_timeouts) {
sys_dlist_t *q = (sys_dlist_t *)wait_q;
sys_dnode_t *cur, *next;
/* skip threads that have an expired timeout */
SYS_DLIST_FOR_EACH_NODE_SAFE(q, cur, next) {
struct k_thread *thread = (struct k_thread *)cur;

View file

@ -189,6 +189,9 @@ uint32_t k_uptime_delta_32(int64_t *reftime)
* Always called from interrupt level, and always only from the system clock
* interrupt.
*/
volatile int _handling_timeouts;
static inline void handle_timeouts(int32_t ticks)
{
sys_dlist_t expired;
@ -222,6 +225,8 @@ static inline void handle_timeouts(int32_t ticks)
sys_dnode_t *next = &head->node;
struct _timeout *timeout = (struct _timeout *)next;
_handling_timeouts = 1;
while (timeout && timeout->delta_ticks_from_prev == 0) {
sys_dlist_remove(next);
@ -238,6 +243,8 @@ static inline void handle_timeouts(int32_t ticks)
irq_unlock(key);
_handle_expired_timeouts(&expired);
_handling_timeouts = 0;
}
#else
#define handle_timeouts(ticks) do { } while ((0))