Commit c46f7f54 authored by Chris Friedt's avatar Chris Friedt Committed by Benjamin Cabé
Browse files

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: default avatarChris Friedt <cfriedt@tenstorrent.com>
parent 582c9834
Loading
Loading
Loading
Loading
+31 −4
Changes for doc/kernel/services/threads/index.rst: 31 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -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
---------------------

+12 −9
Changes for include/zephyr/kernel.h: 12 added lines, 9 removed lines.
Original line number Diff line number Diff line
@@ -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:
 *