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 <peter.mitsis@intel.com>
This commit is contained in:
Peter Mitsis 2023-01-06 13:20:28 -05:00 committed by Stephanos Ioannidis
parent 0037712e68
commit 31dfd84fd5
2 changed files with 8 additions and 4 deletions

View file

@ -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;
}

View file

@ -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);
}
}
}