1 /*
2 * FreeRTOS Kernel V10.2.1
3 * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
6 * this software and associated documentation files (the "Software"), to deal in
7 * the Software without restriction, including without limitation the rights to
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 * the Software, and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in all
13 * copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * http://www.FreeRTOS.org
23 * http://aws.amazon.com/freertos
24 *
25 * 1 tab == 4 spaces!
26 */
27
28
29 #include <stdlib.h>
30 #include "esp_osal.h"
31 #include "list.h"
32
33
34 /*-----------------------------------------------------------
35 * PUBLIC LIST API documented in list.h
36 *----------------------------------------------------------*/
37
vListInitialise(List_t * const pxList)38 void vListInitialise( List_t * const pxList )
39 {
40 /* The list structure contains a list item which is used to mark the
41 end of the list. To initialise the list the list end is inserted
42 as the only list entry. */
43 pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
44
45 /* The list end value is the highest possible value in the list to
46 ensure it remains at the end of the list. */
47 pxList->xListEnd.xItemValue = portMAX_DELAY;
48
49 /* The list end next and previous pointers point to itself so we know
50 when the list is empty. */
51 pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
52 pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */
53
54 pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
55
56 /* Write known values into the list if
57 configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
58 listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
59 listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
60 }
61 /*-----------------------------------------------------------*/
62
vListInitialiseItem(ListItem_t * const pxItem)63 void vListInitialiseItem( ListItem_t * const pxItem )
64 {
65 /* Make sure the list item is not recorded as being on a list. */
66 pxItem->pxContainer = NULL;
67
68 /* Write known values into the list item if
69 configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
70 listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
71 listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
72 }
73 /*-----------------------------------------------------------*/
74
vListInsertEnd(List_t * const pxList,ListItem_t * const pxNewListItem)75 void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )
76 {
77 ListItem_t * const pxIndex = pxList->pxIndex;
78
79 /* Only effective when configASSERT() is also defined, these tests may catch
80 the list data structures being overwritten in memory. They will not catch
81 data errors caused by incorrect configuration or use of FreeRTOS. */
82 listTEST_LIST_INTEGRITY( pxList );
83 listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
84
85 /* Insert a new list item into pxList, but rather than sort the list,
86 makes the new list item the last item to be removed by a call to
87 listGET_OWNER_OF_NEXT_ENTRY(). */
88 pxNewListItem->pxNext = pxIndex;
89 pxNewListItem->pxPrevious = pxIndex->pxPrevious;
90
91 /* Only used during decision coverage testing. */
92 mtCOVERAGE_TEST_DELAY();
93
94 pxIndex->pxPrevious->pxNext = pxNewListItem;
95 pxIndex->pxPrevious = pxNewListItem;
96
97 /* Remember which list the item is in. */
98 pxNewListItem->pxContainer = pxList;
99
100 ( pxList->uxNumberOfItems )++;
101 }
102 /*-----------------------------------------------------------*/
103
vListInsert(List_t * const pxList,ListItem_t * const pxNewListItem)104 void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )
105 {
106 ListItem_t *pxIterator;
107 const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
108
109 /* Only effective when configASSERT() is also defined, these tests may catch
110 the list data structures being overwritten in memory. They will not catch
111 data errors caused by incorrect configuration or use of FreeRTOS. */
112 listTEST_LIST_INTEGRITY( pxList );
113 listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
114
115 /* Insert the new list item into the list, sorted in xItemValue order.
116
117 If the list already contains a list item with the same item value then the
118 new list item should be placed after it. This ensures that TCBs which are
119 stored in ready lists (all of which have the same xItemValue value) get a
120 share of the CPU. However, if the xItemValue is the same as the back marker
121 the iteration loop below will not end. Therefore the value is checked
122 first, and the algorithm slightly modified if necessary. */
123 if( xValueOfInsertion == portMAX_DELAY )
124 {
125 pxIterator = pxList->xListEnd.pxPrevious;
126 }
127 else
128 {
129 /* *** NOTE ***********************************************************
130 If you find your application is crashing here then likely causes are
131 listed below. In addition see https://www.freertos.org/FAQHelp.html for
132 more tips, and ensure configASSERT() is defined!
133 https://www.freertos.org/a00110.html#configASSERT
134
135 1) Stack overflow -
136 see https://www.freertos.org/Stacks-and-stack-overflow-checking.html
137 2) Incorrect interrupt priority assignment, especially on Cortex-M
138 parts where numerically high priority values denote low actual
139 interrupt priorities, which can seem counter intuitive. See
140 https://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition
141 of configMAX_SYSCALL_INTERRUPT_PRIORITY on
142 https://www.freertos.org/a00110.html
143 3) Calling an API function from within a critical section or when
144 the scheduler is suspended, or calling an API function that does
145 not end in "FromISR" from an interrupt.
146 4) Using a queue or semaphore before it has been initialised or
147 before the scheduler has been started (are interrupts firing
148 before vTaskStartScheduler() has been called?).
149 **********************************************************************/
150
151 for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */
152 {
153 /* There is nothing to do here, just iterating to the wanted
154 insertion position. */
155 }
156 }
157
158 pxNewListItem->pxNext = pxIterator->pxNext;
159 pxNewListItem->pxNext->pxPrevious = pxNewListItem;
160 pxNewListItem->pxPrevious = pxIterator;
161 pxIterator->pxNext = pxNewListItem;
162
163 /* Remember which list the item is in. This allows fast removal of the
164 item later. */
165 pxNewListItem->pxContainer = pxList;
166
167 ( pxList->uxNumberOfItems )++;
168 }
169 /*-----------------------------------------------------------*/
170
uxListRemove(ListItem_t * const pxItemToRemove)171 UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
172 {
173 /* The list item knows which list it is in. Obtain the list from the list
174 item. */
175 List_t * const pxList = pxItemToRemove->pxContainer;
176
177 pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
178 pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
179
180 /* Only used during decision coverage testing. */
181 mtCOVERAGE_TEST_DELAY();
182
183 /* Make sure the index is left pointing to a valid item. */
184 if(pxList->pxIndex == pxItemToRemove)
185 {
186 pxList->pxIndex = pxItemToRemove->pxPrevious;
187 }
188 else
189 {
190 mtCOVERAGE_TEST_MARKER();
191 }
192
193 pxItemToRemove->pxContainer = NULL;
194 ( pxList->uxNumberOfItems )--;
195
196 return pxList->uxNumberOfItems;
197 }
198 /*-----------------------------------------------------------*/
199