1.. _stacks_v2: 2 3Stacks 4###### 5 6A :dfn:`stack` is a kernel object that implements a traditional 7last in, first out (LIFO) queue, allowing threads and ISRs 8to add and remove a limited number of integer data values. 9 10.. contents:: 11 :local: 12 :depth: 2 13 14Concepts 15******** 16 17Any number of stacks can be defined (limited only by available RAM). Each stack 18is referenced by its memory address. 19 20A stack has the following key properties: 21 22* A **queue** of integer data values that have been added but not yet removed. 23 The queue is implemented using an array of stack_data_t values 24 and must be aligned on a native word boundary. 25 The stack_data_t type corresponds to the native word size i.e. 32 bits or 26 64 bits depending on the CPU architecture and compilation mode. 27 28* A **maximum quantity** of data values that can be queued in the array. 29 30A stack must be initialized before it can be used. This sets its queue to empty. 31 32A data value can be **added** to a stack by a thread or an ISR. 33The value is given directly to a waiting thread, if one exists; 34otherwise the value is added to the LIFO's queue. 35 36.. note:: 37 If :kconfig:option:`CONFIG_NO_RUNTIME_CHECKS` is enabled, the kernel will *not* detect 38 and prevent attempts to add a data value to a stack that has already reached 39 its maximum quantity of queued values. Adding a data value to a stack that is 40 already full will result in array overflow, and lead to unpredictable behavior. 41 42A data value may be **removed** from a stack by a thread. 43If the stack's queue is empty a thread may choose to wait for it to be given. 44Any number of threads may wait on an empty stack simultaneously. 45When a data item is added, it is given to the highest priority thread 46that has waited longest. 47 48.. note:: 49 The kernel does allow an ISR to remove an item from a stack, however 50 the ISR must not attempt to wait if the stack is empty. 51 52Implementation 53************** 54 55Defining a Stack 56================ 57 58A stack is defined using a variable of type :c:struct:`k_stack`. 59It must then be initialized by calling :c:func:`k_stack_init` or 60:c:func:`k_stack_alloc_init`. In the latter case, a buffer is not 61provided and it is instead allocated from the calling thread's resource 62pool. 63 64The following code defines and initializes an empty stack capable of holding 65up to ten word-sized data values. 66 67.. code-block:: c 68 69 #define MAX_ITEMS 10 70 71 stack_data_t my_stack_array[MAX_ITEMS]; 72 struct k_stack my_stack; 73 74 k_stack_init(&my_stack, my_stack_array, MAX_ITEMS); 75 76Alternatively, a stack can be defined and initialized at compile time 77by calling :c:macro:`K_STACK_DEFINE`. 78 79The following code has the same effect as the code segment above. Observe 80that the macro defines both the stack and its array of data values. 81 82.. code-block:: c 83 84 K_STACK_DEFINE(my_stack, MAX_ITEMS); 85 86Pushing to a Stack 87================== 88 89A data item is added to a stack by calling :c:func:`k_stack_push`. 90 91The following code builds on the example above, and shows how a thread 92can create a pool of data structures by saving their memory addresses 93in a stack. 94 95.. code-block:: c 96 97 /* define array of data structures */ 98 struct my_buffer_type { 99 int field1; 100 ... 101 }; 102 struct my_buffer_type my_buffers[MAX_ITEMS]; 103 104 /* save address of each data structure in a stack */ 105 for (int i = 0; i < MAX_ITEMS; i++) { 106 k_stack_push(&my_stack, (stack_data_t)&my_buffers[i]); 107 } 108 109Popping from a Stack 110==================== 111 112A data item is taken from a stack by calling :c:func:`k_stack_pop`. 113 114The following code builds on the example above, and shows how a thread 115can dynamically allocate an unused data structure. 116When the data structure is no longer required, the thread must push 117its address back on the stack to allow the data structure to be reused. 118 119.. code-block:: c 120 121 struct my_buffer_type *new_buffer; 122 123 k_stack_pop(&buffer_stack, (stack_data_t *)&new_buffer, K_FOREVER); 124 new_buffer->field1 = ... 125 126Suggested Uses 127************** 128 129Use a stack to store and retrieve integer data values in a "last in, 130first out" manner, when the maximum number of stored items is known. 131 132Configuration Options 133********************* 134 135Related configuration options: 136 137* None. 138 139API Reference 140************* 141 142.. doxygengroup:: stack_apis 143