From dde3d6ca9b532a6ea547ce8ab1e215628d3f2410 Mon Sep 17 00:00:00 2001 From: Chen Peng1 Date: Wed, 29 Sep 2021 10:21:58 +0800 Subject: [PATCH] timer: mask interrupts in timer's timeout handler. before running timer's timeout function, we need to make sure that those threads waiting on this timer have been added into the timer's wait queue, so add operations to use timer lock to mask interrupts in z_timer_expiration_handler function to synchronize timer's wait queue. Signed-off-by: Chen Peng1 --- kernel/timer.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/kernel/timer.c b/kernel/timer.c index 5221e2ad377..f2f3a11d945 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -26,6 +26,7 @@ void z_timer_expiration_handler(struct _timeout *t) { struct k_timer *timer = CONTAINER_OF(t, struct k_timer, timeout); struct k_thread *thread; + k_spinlock_key_t key = k_spin_lock(&lock); /* * if the timer is periodic, start it again; don't add _TICK_ALIGN @@ -46,27 +47,23 @@ void z_timer_expiration_handler(struct _timeout *t) } if (!IS_ENABLED(CONFIG_MULTITHREADING)) { + k_spin_unlock(&lock, key); return; } thread = z_waitq_head(&timer->wait_q); if (thread == NULL) { + k_spin_unlock(&lock, key); return; } - /* - * Interrupts _DO NOT_ have to be locked in this specific - * instance of thread unpending because a) this is the only - * place a thread can be taken off this pend queue, and b) the - * only place a thread can be put on the pend queue is at - * thread level, which of course cannot interrupt the current - * context. - */ z_unpend_thread_no_timeout(thread); arch_thread_return_value_set(thread, 0); + k_spin_unlock(&lock, key); + z_ready_thread(thread); }