From 31dfd84fd5c89a068c00521902dcf47e1c295ed4 Mon Sep 17 00:00:00 2001 From: Peter Mitsis Date: Fri, 6 Jan 2023 13:20:28 -0500 Subject: [PATCH] kernel: pipes: Change method of unpending waiters By the time the working list of readers/writers is processed, it is possible that waiting reader/writer being processed had timed out and is no longer on the wait queue. As such, we can not blindly wake the next thread as that next thread might not be the thread we had just been processing. To address this, the calls to z_sched_wake() have been replaced with z_unpend_thread() and z_ready_thread() so that a specific thread can be safely targeted for waking. Signed-off-by: Peter Mitsis --- kernel/pipes.c | 8 +++++--- kernel/sched.c | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/kernel/pipes.c b/kernel/pipes.c index 857005d1e9a..0c108c3c834 100644 --- a/kernel/pipes.c +++ b/kernel/pipes.c @@ -349,9 +349,10 @@ static size_t pipe_write(struct k_pipe *pipe, sys_dlist_t *src_list, } } else if (dest->bytes_to_xfer == 0U) { - /* A thread's read request has been satisfied. */ + /* The thread's read request has been satisfied. */ - (void) z_sched_wake(&pipe->wait_q.readers, 0, NULL); + z_unpend_thread(dest->thread); + z_ready_thread(dest->thread); *reschedule = true; } @@ -586,7 +587,8 @@ static int pipe_get_internal(k_spinlock_key_t key, struct k_pipe *pipe, /* The thread's write request has been satisfied. */ - (void) z_sched_wake(&pipe->wait_q.writers, 0, NULL); + z_unpend_thread(src_desc->thread); + z_ready_thread(src_desc->thread); reschedule_needed = true; } diff --git a/kernel/sched.c b/kernel/sched.c index 3cc81dab46a..b9c326c494d 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -788,7 +788,9 @@ static inline void unpend_thread_no_timeout(struct k_thread *thread) ALWAYS_INLINE void z_unpend_thread_no_timeout(struct k_thread *thread) { LOCKED(&sched_spinlock) { - unpend_thread_no_timeout(thread); + if (thread->base.pended_on != NULL) { + unpend_thread_no_timeout(thread); + } } }