1.. _lifos_v2: 2 3LIFOs 4##### 5 6A :dfn:`LIFO` is a kernel object that implements a traditional 7last in, first out (LIFO) queue, allowing threads and ISRs 8to add and remove data items of any size. 9 10.. contents:: 11 :local: 12 :depth: 2 13 14Concepts 15******** 16 17Any number of LIFOs can be defined (limited only by available RAM). Each LIFO is 18referenced by its memory address. 19 20A LIFO has the following key properties: 21 22* A **queue** of data items that have been added but not yet removed. 23 The queue is implemented as a simple linked list. 24 25A LIFO must be initialized before it can be used. This sets its queue to empty. 26 27LIFO data items must be aligned on a word boundary, as the kernel reserves 28the first word of an item for use as a pointer to the next data item in the 29queue. Consequently, a data item that holds N bytes of application data 30requires N+4 (or N+8) bytes of memory. There are no alignment or reserved 31space requirements for data items if they are added with 32:c:func:`k_lifo_alloc_put`, instead additional memory is temporarily 33allocated from the calling thread's resource pool. 34 35.. note:: 36 LIFO data items are restricted to single active instance across all LIFO 37 data queues. Any attempt to re-add a LIFO data item to a queue before 38 it has been removed from the queue to which it was previously added will 39 result in undefined behavior. 40 41A data item may be **added** to a LIFO by a thread or an ISR. 42The item is given directly to a waiting thread, if one exists; 43otherwise the item is added to the LIFO's queue. 44There is no limit to the number of items that may be queued. 45 46A data item may be **removed** from a LIFO by a thread. If the LIFO's queue 47is empty a thread may choose to wait for a data item to be given. 48Any number of threads may wait on an empty LIFO simultaneously. 49When a data item is added, it is given to the highest priority thread 50that has waited longest. 51 52.. note:: 53 The kernel does allow an ISR to remove an item from a LIFO, however 54 the ISR must not attempt to wait if the LIFO is empty. 55 56Implementation 57************** 58 59Defining a LIFO 60=============== 61 62A LIFO is defined using a variable of type :c:struct:`k_lifo`. 63It must then be initialized by calling :c:func:`k_lifo_init`. 64 65The following defines and initializes an empty LIFO. 66 67.. code-block:: c 68 69 struct k_lifo my_lifo; 70 71 k_lifo_init(&my_lifo); 72 73Alternatively, an empty LIFO can be defined and initialized at compile time 74by calling :c:macro:`K_LIFO_DEFINE`. 75 76The following code has the same effect as the code segment above. 77 78.. code-block:: c 79 80 K_LIFO_DEFINE(my_lifo); 81 82Writing to a LIFO 83================= 84 85A data item is added to a LIFO by calling :c:func:`k_lifo_put`. 86 87The following code builds on the example above, and uses the LIFO 88to send data to one or more consumer threads. 89 90.. code-block:: c 91 92 struct data_item_t { 93 void *LIFO_reserved; /* 1st word reserved for use by LIFO */ 94 ... 95 }; 96 97 struct data_item_t tx data; 98 99 void producer_thread(int unused1, int unused2, int unused3) 100 { 101 while (1) { 102 /* create data item to send */ 103 tx_data = ... 104 105 /* send data to consumers */ 106 k_lifo_put(&my_lifo, &tx_data); 107 108 ... 109 } 110 } 111 112A data item can be added to a LIFO with :c:func:`k_lifo_alloc_put`. 113With this API, there is no need to reserve space for the kernel's use in 114the data item, instead additional memory will be allocated from the calling 115thread's resource pool until the item is read. 116 117Reading from a LIFO 118=================== 119 120A data item is removed from a LIFO by calling :c:func:`k_lifo_get`. 121 122The following code builds on the example above, and uses the LIFO 123to obtain data items from a producer thread, 124which are then processed in some manner. 125 126.. code-block:: c 127 128 void consumer_thread(int unused1, int unused2, int unused3) 129 { 130 struct data_item_t *rx_data; 131 132 while (1) { 133 rx_data = k_lifo_get(&my_lifo, K_FOREVER); 134 135 /* process LIFO data item */ 136 ... 137 } 138 } 139 140Suggested Uses 141************** 142 143Use a LIFO to asynchronously transfer data items of arbitrary size 144in a "last in, first out" manner. 145 146Configuration Options 147********************* 148 149Related configuration options: 150 151* None. 152 153API Reference 154************* 155 156.. doxygengroup:: lifo_apis 157