• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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