From b0afc266d19cdc8399f17573d0632850cfc3194d Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Mon, 23 May 2016 20:50:51 +0100 Subject: [PATCH] atomkernel: Support thread entry points running to completion. Ports which use a thread_shell() can allow the entry point to finish and return back to the thread_shell(), which sets the terminated flag and calls the scheduler to force another thread to be scheduled in. Currently implemented in the ARM and AVR ports. --- kernel/atom.h | 1 + kernel/atomkernel.c | 7 ++++--- ports/arm/atomport.c | 2 +- ports/avr/atomport.c | 5 +++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/kernel/atom.h b/kernel/atom.h index 2ee75a5..164c968 100755 --- a/kernel/atom.h +++ b/kernel/atom.h @@ -77,6 +77,7 @@ typedef struct atom_tcb uint8_t suspended; /* TRUE if task is currently suspended */ uint8_t suspend_wake_status; /* Status returned to woken suspend calls */ ATOM_TIMER *suspend_timo_cb; /* Callback registered for suspension timeouts */ + uint8_t terminated; /* TRUE if task is being terminated (run to completion) */ /* Details used if thread stack-checking is required */ #ifdef ATOM_STACK_CHECKING diff --git a/kernel/atomkernel.c b/kernel/atomkernel.c index db9273f..06ab2cc 100755 --- a/kernel/atomkernel.c +++ b/kernel/atomkernel.c @@ -241,10 +241,11 @@ void atomSched (uint8_t timer_tick) CRITICAL_START (); /** - * If the current thread is going into suspension, then - * unconditionally dequeue the next thread for execution. + * If the current thread is going into suspension or is being + * terminated (run to completion), then unconditionally dequeue + * the next thread for execution. */ - if (curr_tcb->suspended == TRUE) + if ((curr_tcb->suspended == TRUE) || (curr_tcb->terminated == TRUE)) { /** * Dequeue the next ready to run thread. There will always be diff --git a/ports/arm/atomport.c b/ports/arm/atomport.c index 1383a8a..fc057ff 100644 --- a/ports/arm/atomport.c +++ b/ports/arm/atomport.c @@ -97,7 +97,7 @@ static void thread_shell (void) _reclaim_reent (&(curr_tcb->port_priv.reent)); /* Thread has run to completion: remove it from the ready list */ - curr_tcb->suspended = TRUE; + curr_tcb->terminated = TRUE; atomSched (FALSE); } diff --git a/ports/avr/atomport.c b/ports/avr/atomport.c index 9ae5555..362e66d 100644 --- a/ports/avr/atomport.c +++ b/ports/avr/atomport.c @@ -111,8 +111,9 @@ static void thread_shell (void) curr_tcb->entry_point(curr_tcb->entry_param); } - /* Not reached - threads should never return from the entry point */ - + /* Thread has run to completion: remove it from the ready list */ + curr_tcb->terminated = TRUE; + atomSched (FALSE); }