doc: kernel: threads: add dynamic thread stack docs

Add documentation to indicate that, aside from static thread
stack allocation, Zephyr supports dynamically allocated thread
stacks.

Signed-off-by: Chris Friedt <cfriedt@tenstorrent.com>
This commit is contained in:
Chris Friedt 2025-04-05 16:45:40 -04:00 committed by Benjamin Cabé
commit c46f7f54e8
2 changed files with 43 additions and 13 deletions

View file

@ -189,8 +189,12 @@ require their regions to be of some power of two in size, and aligned to its
own size.
Because of this, portable code can't simply pass an arbitrary character buffer
to :c:func:`k_thread_create`. Special macros exist to instantiate stacks,
prefixed with ``K_KERNEL_STACK`` and ``K_THREAD_STACK``.
to :c:func:`k_thread_create`. Special macros exist to instantiate stacks
statically, prefixed with ``K_KERNEL_STACK`` and ``K_THREAD_STACK``.
Additionally, stacks may be instantiated dynamically using
:c:func:`k_thread_stack_alloc` and subsequently freed with
:c:func:`k_thread_stack_free`.
Kernel-only Stacks
==================
@ -411,8 +415,9 @@ Spawning a Thread
A thread is spawned by defining its stack area and its thread control block,
and then calling :c:func:`k_thread_create`.
The stack area must be defined using :c:macro:`K_THREAD_STACK_DEFINE` or
:c:macro:`K_KERNEL_STACK_DEFINE` to ensure it is properly set up in memory.
The stack area may be statically allocated using
:c:macro:`K_THREAD_STACK_DEFINE` or :c:macro:`K_KERNEL_STACK_DEFINE` to ensure
it is properly set up in memory.
The size parameter for the stack must be one of three values:
@ -426,6 +431,9 @@ The size parameter for the stack must be one of three values:
macros, the return value of :c:macro:`K_KERNEL_STACK_SIZEOF()` for that
object.
Alternatively, the stack area may be dynamically allocated using
:c:func:`k_thread_stack_alloc` and freed using :c:func:`k_thread_stack_free`.
The thread spawning function returns its thread id, which can be used
to reference the thread.
@ -470,6 +478,25 @@ The following code has the same effect as the code segment above.
thread immediately. The corresponding parameter to :c:macro:`K_THREAD_DEFINE`
is a duration in integral milliseconds, so the equivalent argument is 0.
The following code dynamically allocates a thread stack, waits until the thread
has joined, and then frees the dynamically allocated thread stack.
.. code-block:: c
extern void my_entry_point(void *, void *, void *);
k_tid_t my_tid;
void *my_stack_area;
my_stack_area = k_thread_stack_alloc(CONFIG_DYNAMIC_THREAD_STACK_SIZE);
my_tid = k_thread_create(&my_thread_data, my_stack_area,
CONFIG_DYNAMIC_THREAD_STACK_SIZE,
my_entry_point,
NULL, NULL, NULL,
MY_PRIORITY, 0, K_NO_WAIT);
k_thread_join(my_tid, K_FOREVER);
k_thread_stack_free(my_stack_area);
User Mode Constraints
---------------------

View file

@ -332,14 +332,15 @@ void k_thread_foreach_unlocked_filter_by_cpu(unsigned int cpu,
/**
* @brief Dynamically allocate a thread stack.
*
* Dynamically allocate a thread stack either from a pool of thread stacks of size
* @kconfig{CONFIG_DYNAMIC_THREAD_POOL_SIZE}, or from the system heap. Order is determined by the
* kconfig{CONFIG_DYNAMIC_THREAD_PREFER_ALLOC} and @kconfig{CONFIG_DYNAMIC_THREAD_PREFER_POOL}
* options. Thread stacks from the pool are of maximum size
* @kconfig{CONFIG_DYNAMIC_THREAD_STACK_SIZE}.
* Dynamically allocate a thread stack either from a pool of thread stacks of
* size @kconfig{CONFIG_DYNAMIC_THREAD_POOL_SIZE}, or from the system heap.
* Order is determined by the @kconfig{CONFIG_DYNAMIC_THREAD_PREFER_ALLOC} and
* @kconfig{CONFIG_DYNAMIC_THREAD_PREFER_POOL} options. Thread stacks from the
* pool are of maximum size @kconfig{CONFIG_DYNAMIC_THREAD_STACK_SIZE}.
*
* Relevant stack creation flags include:
* - @ref K_USER allocate a userspace thread (requires @kconfig{CONFIG_USERSPACE})
* @note When no longer required, thread stacks allocated with
* `k_thread_stack_alloc()` must be freed with @ref k_thread_stack_free to
* avoid leaking memory.
*
* @param size Stack size in bytes.
* @param flags Stack creation flags, or 0.
@ -347,6 +348,9 @@ void k_thread_foreach_unlocked_filter_by_cpu(unsigned int cpu,
* @retval the allocated thread stack on success.
* @retval NULL on failure.
*
* Relevant stack creation flags include:
* - @ref K_USER allocate a userspace thread (requires @kconfig{CONFIG_USERSPACE})
*
* @see @kconfig{CONFIG_DYNAMIC_THREAD}
*/
__syscall k_thread_stack_t *k_thread_stack_alloc(size_t size, int flags);
@ -389,8 +393,7 @@ __syscall int k_thread_stack_free(k_thread_stack_t *stack);
* enabled.
*
* Alternatively, the stack may be dynamically allocated using
* @ref k_thread_stack_alloc. If this is the case, then the stack should
* be freed using @ref k_thread_stack_free after joining the thread.
* @ref k_thread_stack_alloc.
*
* The stack_size parameter has constraints. It must either be:
*