list.c 8.1 KB

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