kernel: add context pointer to thread->fn_abort

For compatibility layers like CMSIS where thread objects
are drawn from a pool, provide a context pointer to the
exited thread object so it may be freed.

This is somewhat obscure and has no supporting APIs or
overview documentation and should be considered a private
kernel feature. Applications should really be using
k_thread_join() instead.

Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2020-09-03 17:56:24 -07:00 committed by Anas Nashif
commit 933b420235
3 changed files with 28 additions and 5 deletions

View file

@ -286,8 +286,26 @@ struct k_thread {
/**
* abort function
* */
void (*fn_abort)(void);
*
* This function pointer, if non-NULL, will be run once after the
* thread has completely exited. It may run in the context of:
* - the idle thread if the thread self-exited
* - another thread calling k_thread_abort()
* - a fatal exception handler on a special stack
*
* It will never run in the context of the thread itself.
*
* A pointer to the thread object that was aborted is provided. At the
* time this runs, this thread object has completely exited. It may
* be re-used with k_thread_create() or return it to a heap or slab
* pool.
*
* This function does not run with any kind of lock active and
* there is the possibility of races leading to undefined behavior
* if other threads are attempting to free or recycle this object
* concurrently.
*/
void (*fn_abort)(struct k_thread *aborted);
#if defined(CONFIG_THREAD_MONITOR)
/** thread entry and parameters description */

View file

@ -520,7 +520,7 @@ static _wait_q_t *pended_on(struct k_thread *thread)
void z_thread_single_abort(struct k_thread *thread)
{
void (*fn_abort)(void) = NULL;
void (*fn_abort)(struct k_thread *aborted) = NULL;
__ASSERT(!(thread->base.user_options & K_ESSENTIAL),
"essential thread aborted");
@ -629,7 +629,8 @@ void z_thread_single_abort(struct k_thread *thread)
}
if (fn_abort != NULL) {
fn_abort();
/* Thread object provided to be freed or recycled */
fn_abort(thread);
}
}

View file

@ -107,10 +107,14 @@ void test_threads_abort_repeat(void)
bool abort_called;
void *block;
static void abort_function(void)
static void abort_function(struct k_thread *aborted)
{
printk("Child thread's abort handler called\n");
abort_called = true;
zassert_equal(aborted, &tdata, "wrong thread pointer");
zassert_not_equal(k_current_get(), aborted,
"fn_abort ran on its own thread");
k_free(block);
}