From 22642cf3099882732f6279f3e6fc92d80efcfef4 Mon Sep 17 00:00:00 2001 From: Andy Ross Date: Mon, 2 Apr 2018 18:24:58 -0700 Subject: [PATCH] kernel: Clean up _unpend_thread() API Almost everywhere this was called, it was immediately followed by _abort_thread_timeout(), for obvious reasons. The only exceptions were in timeout and k_timer expiration (unifying these two would be another good cleanup), which are peripheral parts of the scheduler and can plausibly use a more "internal" API. So make the common case the default, and expose the old behavior as _unpend_thread_no_timeout(). (Along with identical changes for _unpend_first_thread) Saves code bytes and simplifies scheduler surface area for future synchronization work. Signed-off-by: Andy Ross --- kernel/include/ksched.h | 16 ++++++++-------- kernel/include/timeout_q.h | 2 +- kernel/mailbox.c | 2 -- kernel/mem_slab.c | 1 - kernel/mempool.c | 1 - kernel/msg_q.c | 3 --- kernel/mutex.c | 1 - kernel/pipes.c | 1 - kernel/poll.c | 1 - kernel/queue.c | 1 - kernel/sched.c | 25 +++++++++++++++++++++++++ kernel/sem.c | 3 +-- kernel/stack.c | 3 +-- kernel/thread.c | 2 +- kernel/timer.c | 15 ++++++++------- lib/posix/pthread_common.c | 1 - 16 files changed, 45 insertions(+), 33 deletions(-) diff --git a/kernel/include/ksched.h b/kernel/include/ksched.h index 07d3bba5585..e0b38227e78 100644 --- a/kernel/include/ksched.h +++ b/kernel/include/ksched.h @@ -489,27 +489,27 @@ _find_first_thread_to_unpend(_wait_q_t *wait_q, struct k_thread *from) /* Unpend a thread from the wait queue it is on. Thread must be pending. */ /* must be called with interrupts locked */ -static inline void _unpend_thread(struct k_thread *thread) -{ - __ASSERT(thread->base.thread_state & _THREAD_PENDING, ""); +void _unpend_thread(struct k_thread *thread); - sys_dlist_remove(&thread->base.k_q_node); - _mark_thread_as_not_pending(thread); -} +/* Same, but does not abort current timeout */ +void _unpend_thread_no_timeout(struct k_thread *thread); /* unpend the first thread from a wait queue */ /* must be called with interrupts locked */ -static inline struct k_thread *_unpend_first_thread(_wait_q_t *wait_q) +struct k_thread *_unpend_first_thread(_wait_q_t *wait_q); + +static inline struct k_thread *_unpend1_no_timeout(_wait_q_t *wait_q) { struct k_thread *thread = _find_first_thread_to_unpend(wait_q, NULL); if (thread) { - _unpend_thread(thread); + _unpend_thread_no_timeout(thread); } return thread; } + #ifdef CONFIG_USERSPACE /** * Indicate whether the currently running thread has been configured to be diff --git a/kernel/include/timeout_q.h b/kernel/include/timeout_q.h index dc79bb3937d..3c878444248 100644 --- a/kernel/include/timeout_q.h +++ b/kernel/include/timeout_q.h @@ -69,7 +69,7 @@ static inline void _unpend_thread_timing_out(struct k_thread *thread, struct _timeout *timeout_obj) { if (timeout_obj->wait_q) { - _unpend_thread(thread); + _unpend_thread_no_timeout(thread); thread->base.timeout.wait_q = NULL; } } diff --git a/kernel/mailbox.c b/kernel/mailbox.c index c0723d91463..4b4446f57fb 100644 --- a/kernel/mailbox.c +++ b/kernel/mailbox.c @@ -260,7 +260,6 @@ static int mbox_message_put(struct k_mbox *mbox, struct k_mbox_msg *tx_msg, if (mbox_message_match(tx_msg, rx_msg) == 0) { /* take receiver out of rx queue */ _unpend_thread(receiving_thread); - _abort_thread_timeout(receiving_thread); /* ready receiver for execution */ _set_thread_return_value(receiving_thread, 0); @@ -441,7 +440,6 @@ int k_mbox_get(struct k_mbox *mbox, struct k_mbox_msg *rx_msg, void *buffer, if (mbox_message_match(tx_msg, rx_msg) == 0) { /* take sender out of mailbox's tx queue */ _unpend_thread(sending_thread); - _abort_thread_timeout(sending_thread); irq_unlock(key); diff --git a/kernel/mem_slab.c b/kernel/mem_slab.c index b51315a5ec1..f7104b9e266 100644 --- a/kernel/mem_slab.c +++ b/kernel/mem_slab.c @@ -119,7 +119,6 @@ void k_mem_slab_free(struct k_mem_slab *slab, void **mem) if (pending_thread) { _set_thread_return_value_with_data(pending_thread, 0, *mem); - _abort_thread_timeout(pending_thread); _ready_thread(pending_thread); } else { **(char ***)mem = slab->free_list; diff --git a/kernel/mempool.c b/kernel/mempool.c index d57205cefa8..91b7ff77108 100644 --- a/kernel/mempool.c +++ b/kernel/mempool.c @@ -103,7 +103,6 @@ void k_mem_pool_free_id(struct k_mem_block_id *id) struct k_thread *th = (void *)sys_dlist_peek_head(&p->wait_q); _unpend_thread(th); - _abort_thread_timeout(th); _ready_thread(th); need_sched = 1; } diff --git a/kernel/msg_q.c b/kernel/msg_q.c index f1b9f533db0..c92f6319bd7 100644 --- a/kernel/msg_q.c +++ b/kernel/msg_q.c @@ -92,7 +92,6 @@ int _impl_k_msgq_put(struct k_msgq *q, void *data, s32_t timeout) q->msg_size); /* wake up waiting thread */ _set_thread_return_value(pending_thread, 0); - _abort_thread_timeout(pending_thread); _ready_thread(pending_thread); _reschedule(key); return 0; @@ -182,7 +181,6 @@ int _impl_k_msgq_get(struct k_msgq *q, void *data, s32_t timeout) /* wake up waiting thread */ _set_thread_return_value(pending_thread, 0); - _abort_thread_timeout(pending_thread); _ready_thread(pending_thread); _reschedule(key); return 0; @@ -222,7 +220,6 @@ void _impl_k_msgq_purge(struct k_msgq *q) /* wake up any threads that are waiting to write */ while ((pending_thread = _unpend_first_thread(&q->wait_q)) != NULL) { _set_thread_return_value(pending_thread, -ENOMSG); - _abort_thread_timeout(pending_thread); _ready_thread(pending_thread); } diff --git a/kernel/mutex.c b/kernel/mutex.c index 8807eb05592..5bdf5b925d2 100644 --- a/kernel/mutex.c +++ b/kernel/mutex.c @@ -231,7 +231,6 @@ void _impl_k_mutex_unlock(struct k_mutex *mutex) mutex, new_owner, new_owner ? new_owner->base.prio : -1000); if (new_owner) { - _abort_thread_timeout(new_owner); _ready_thread(new_owner); irq_unlock(key); diff --git a/kernel/pipes.c b/kernel/pipes.c index d32190973f3..5b86bffc5c6 100644 --- a/kernel/pipes.c +++ b/kernel/pipes.c @@ -335,7 +335,6 @@ static bool pipe_xfer_prepare(sys_dlist_t *xfer_list, * Add it to the transfer list. */ _unpend_thread(thread); - _abort_thread_timeout(thread); sys_dlist_append(xfer_list, &thread->base.k_q_node); } diff --git a/kernel/poll.c b/kernel/poll.c index 20a5825e980..0b5f0e90017 100644 --- a/kernel/poll.c +++ b/kernel/poll.c @@ -285,7 +285,6 @@ static int signal_poll_event(struct k_poll_event *event, u32_t state) } _unpend_thread(thread); - _abort_thread_timeout(thread); _set_thread_return_value(thread, state == K_POLL_STATE_NOT_READY ? -EINTR : 0); diff --git a/kernel/queue.c b/kernel/queue.c index e8ee3305acb..5f5a18bc9a4 100644 --- a/kernel/queue.c +++ b/kernel/queue.c @@ -61,7 +61,6 @@ void k_queue_init(struct k_queue *queue) #if !defined(CONFIG_POLL) static void prepare_thread_to_run(struct k_thread *thread, void *data) { - _abort_thread_timeout(thread); _ready_thread(thread); _set_thread_return_value_with_data(thread, 0, data); } diff --git a/kernel/sched.c b/kernel/sched.c index 41f30124762..3c5af4b15b9 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -230,6 +230,31 @@ inserted: #endif } +void _unpend_thread_no_timeout(struct k_thread *thread) +{ + __ASSERT(thread->base.thread_state & _THREAD_PENDING, ""); + + sys_dlist_remove(&thread->base.k_q_node); + _mark_thread_as_not_pending(thread); +} + +void _unpend_thread(struct k_thread *thread) +{ + _unpend_thread_no_timeout(thread); + _abort_thread_timeout(thread); +} + +struct k_thread *_unpend_first_thread(_wait_q_t *wait_q) +{ + struct k_thread *t = _unpend1_no_timeout(wait_q); + + if (t) { + _abort_thread_timeout(t); + } + + return t; +} + /* Block the current thread and swap to the next. Releases the * irq_lock, does a _Swap and returns the return value set at wakeup * time diff --git a/kernel/sem.c b/kernel/sem.c index 07148c1943a..400bdd44994 100644 --- a/kernel/sem.c +++ b/kernel/sem.c @@ -98,7 +98,6 @@ static void do_sem_give(struct k_sem *sem) struct k_thread *thread = _unpend_first_thread(&sem->wait_q); if (thread) { - (void)_abort_thread_timeout(thread); _ready_thread(thread); _set_thread_return_value(thread, 0); } else { @@ -121,7 +120,7 @@ void _sem_give_non_preemptible(struct k_sem *sem) { struct k_thread *thread; - thread = _unpend_first_thread(&sem->wait_q); + thread = _unpend1_no_timeout(&sem->wait_q); if (!thread) { increment_count_up_to_limit(sem); return; diff --git a/kernel/stack.c b/kernel/stack.c index 68aa9c70680..2fe2ed8cfa5 100644 --- a/kernel/stack.c +++ b/kernel/stack.c @@ -80,12 +80,11 @@ void _impl_k_stack_push(struct k_stack *stack, u32_t data) first_pending_thread = _unpend_first_thread(&stack->wait_q); if (first_pending_thread) { - _abort_thread_timeout(first_pending_thread); _ready_thread(first_pending_thread); _set_thread_return_value_with_data(first_pending_thread, 0, (void *)data); - _reschedule_noyield(key); + _reschedule(key); return; } else { *(stack->next) = data; diff --git a/kernel/thread.c b/kernel/thread.c index 80649b9ac0e..f6e6d3021b2 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -501,7 +501,7 @@ void _k_thread_single_abort(struct k_thread *thread) _remove_thread_from_ready_q(thread); } else { if (_is_thread_pending(thread)) { - _unpend_thread(thread); + _unpend_thread_no_timeout(thread); } if (_is_thread_timeout_active(thread)) { _abort_thread_timeout(thread); diff --git a/kernel/timer.c b/kernel/timer.c index 4cc7b741638..ea1ac6bdea0 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -75,13 +75,14 @@ void _timer_expiration_handler(struct _timeout *t) } /* - * Interrupts _DO NOT_ have to be locked in this specific instance of - * calling _unpend_thread() 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. + * 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. */ - _unpend_thread(thread); + _unpend_thread_no_timeout(thread); key = irq_lock(); _ready_thread(thread); @@ -163,7 +164,7 @@ void _impl_k_timer_stop(struct k_timer *timer) } key = irq_lock(); - struct k_thread *pending_thread = _unpend_first_thread(&timer->wait_q); + struct k_thread *pending_thread = _unpend1_no_timeout(&timer->wait_q); if (pending_thread) { _ready_thread(pending_thread); diff --git a/lib/posix/pthread_common.c b/lib/posix/pthread_common.c index 2ffd49ad0d8..52766bab9ba 100644 --- a/lib/posix/pthread_common.c +++ b/lib/posix/pthread_common.c @@ -15,7 +15,6 @@ void ready_one_thread(_wait_q_t *wq) struct k_thread *th = _unpend_first_thread(wq); if (th) { - _abort_thread_timeout(th); _ready_thread(th); } }