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:
parent
afe42bd129
commit
933b420235
3 changed files with 28 additions and 5 deletions
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue