slist.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /*
  2. *********************************************************************************************************
  3. * uC/Common
  4. * Common Features for Micrium Stacks
  5. *
  6. * Copyright 2013-2020 Silicon Laboratories Inc. www.silabs.com
  7. *
  8. * SPDX-License-Identifier: APACHE-2.0
  9. *
  10. * This software is subject to an open source license and is distributed by
  11. * Silicon Laboratories Inc. pursuant to the terms of the Apache License,
  12. * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
  13. *
  14. *********************************************************************************************************
  15. */
  16. /*
  17. *********************************************************************************************************
  18. *
  19. * uC/Common - Singly-linked Lists (SList)
  20. *
  21. * Filename : slist.c
  22. * Version : V1.02.00
  23. *********************************************************************************************************
  24. */
  25. /*
  26. *********************************************************************************************************
  27. *********************************************************************************************************
  28. * INCLUDE FILES
  29. *********************************************************************************************************
  30. *********************************************************************************************************
  31. */
  32. #define MICRIUM_SOURCE
  33. #define COLL_SLIST_MODULE
  34. #include "slist.h"
  35. #include <lib_def.h>
  36. #include <cpu_core.h>
  37. /*
  38. *********************************************************************************************************
  39. *********************************************************************************************************
  40. * GLOBAL FUNCTIONS
  41. *********************************************************************************************************
  42. *********************************************************************************************************
  43. */
  44. /*
  45. *********************************************************************************************************
  46. * SList_Init()
  47. *
  48. * Description : Initializes a singly-linked list.
  49. *
  50. * Argument(s) : p_head_ptr Pointer to pointer of head element of list.
  51. *
  52. * Return(s) : none.
  53. *
  54. * Note(s) : none.
  55. *********************************************************************************************************
  56. */
  57. void SList_Init (SLIST_MEMBER **p_head_ptr)
  58. {
  59. *p_head_ptr = DEF_NULL;
  60. }
  61. /*
  62. *********************************************************************************************************
  63. * SList_Push()
  64. *
  65. * Description : Add given item at beginning of list.
  66. *
  67. * Argument(s) : p_head_ptr Pointer to pointer of head element of list.
  68. *
  69. * p_item Pointer to item to add.
  70. *
  71. * Return(s) : none.
  72. *
  73. * Note(s) : none.
  74. *********************************************************************************************************
  75. */
  76. void SList_Push (SLIST_MEMBER **p_head_ptr,
  77. SLIST_MEMBER *p_item)
  78. {
  79. p_item->p_next = *p_head_ptr;
  80. *p_head_ptr = p_item;
  81. }
  82. /*
  83. *********************************************************************************************************
  84. * SList_PushBack()
  85. *
  86. * Description : Add item at end of list.
  87. *
  88. * Argument(s) : p_head_ptr Pointer to pointer of head element of list.
  89. *
  90. * p_item Pointer to item to add.
  91. *
  92. * Return(s) : none.
  93. *
  94. * Note(s) : none.
  95. *********************************************************************************************************
  96. */
  97. void SList_PushBack (SLIST_MEMBER **p_head_ptr,
  98. SLIST_MEMBER *p_item)
  99. {
  100. SLIST_MEMBER **p_next_ptr = p_head_ptr;
  101. while (*p_next_ptr != DEF_NULL) {
  102. p_next_ptr = &((*p_next_ptr)->p_next);
  103. }
  104. p_item->p_next = DEF_NULL;
  105. *p_next_ptr = p_item;
  106. }
  107. /*
  108. *********************************************************************************************************
  109. * SList_Pop()
  110. *
  111. * Description : Removes and returns first element of list.
  112. *
  113. * Argument(s) : p_head_ptr Pointer to pointer of head element of list.
  114. *
  115. * Return(s) : Pointer to item that was at top of the list.
  116. *
  117. * Note(s) : none.
  118. *********************************************************************************************************
  119. */
  120. SLIST_MEMBER *SList_Pop (SLIST_MEMBER **p_head_ptr)
  121. {
  122. SLIST_MEMBER *p_item;
  123. p_item = *p_head_ptr;
  124. if (p_item == DEF_NULL) {
  125. return (DEF_NULL);
  126. }
  127. *p_head_ptr = p_item->p_next;
  128. p_item->p_next = DEF_NULL;
  129. return (p_item);
  130. }
  131. /*
  132. *********************************************************************************************************
  133. * SList_Add()
  134. *
  135. * Description : Add item after given item.
  136. *
  137. * Argument(s) : p_item Pointer to item to add.
  138. *
  139. * p_pos Pointer to item after which the item to add will be inserted.
  140. *
  141. * Return(s) : none.
  142. *
  143. * Note(s) : none.
  144. *********************************************************************************************************
  145. */
  146. void SList_Add (SLIST_MEMBER *p_item,
  147. SLIST_MEMBER *p_pos)
  148. {
  149. p_item->p_next = p_pos->p_next;
  150. p_pos->p_next = p_item;
  151. }
  152. /*
  153. *********************************************************************************************************
  154. * SList_Rem()
  155. *
  156. * Description : Remove item from list.
  157. *
  158. * Argument(s) : p_head_ptr Pointer to pointer of head element of list.
  159. *
  160. * p_item Pointer to item to remove.
  161. *
  162. * Return(s) : none.
  163. *
  164. * Note(s) : (1) A CPU_SW_EXCEPTION() is thrown if the item is not found within the list.
  165. *********************************************************************************************************
  166. */
  167. void SList_Rem (SLIST_MEMBER **p_head_ptr,
  168. SLIST_MEMBER *p_item)
  169. {
  170. SLIST_MEMBER **p_next_ptr;
  171. for (p_next_ptr = p_head_ptr; *p_next_ptr != DEF_NULL; p_next_ptr = &((*p_next_ptr)->p_next)) {
  172. if (*p_next_ptr == p_item) {
  173. *p_next_ptr = p_item->p_next;
  174. return;
  175. }
  176. }
  177. CPU_SW_EXCEPTION(;); /* See Note #1. */
  178. }
  179. /*
  180. *********************************************************************************************************
  181. * SList_Sort()
  182. *
  183. * Description : Sorts list items.
  184. *
  185. * Argument(s) : p_head_ptr Pointer to pointer of head element of list.
  186. *
  187. * cmp_fnct Pointer to function to use for sorting the list.
  188. * p_item_l Pointer to left item.
  189. * p_item_r Pointer to right item.
  190. * Returns whether the two items are ordered (DEF_YES) or not (DEF_NO).
  191. *
  192. * Return(s) : none.
  193. *
  194. * Note(s) : none.
  195. *********************************************************************************************************
  196. */
  197. void SList_Sort (SLIST_MEMBER **p_head_ptr,
  198. CPU_BOOLEAN (*cmp_fnct)(SLIST_MEMBER *p_item_l,
  199. SLIST_MEMBER *p_item_r))
  200. {
  201. CPU_BOOLEAN swapped;
  202. SLIST_MEMBER **pp_item_l;
  203. do {
  204. swapped = DEF_NO;
  205. pp_item_l = p_head_ptr;
  206. /* Loop until end of list is found. */
  207. while ((*pp_item_l != DEF_NULL) && ((*pp_item_l)->p_next != DEF_NULL)) {
  208. SLIST_MEMBER *p_item_r = (*pp_item_l)->p_next;
  209. CPU_BOOLEAN ordered;
  210. ordered = cmp_fnct(*pp_item_l, p_item_r); /* Call provided compare fnct. */
  211. if (ordered == DEF_NO) { /* If order is not correct, swap items. */
  212. SLIST_MEMBER *p_tmp = p_item_r->p_next;
  213. p_item_r->p_next = *pp_item_l; /* Swap the two items. */
  214. (*pp_item_l)->p_next = p_tmp;
  215. *pp_item_l = p_item_r;
  216. pp_item_l = &(p_item_r->p_next);
  217. swapped = DEF_YES; /* Indicate a swap has been done. */
  218. } else {
  219. pp_item_l = &((*pp_item_l)->p_next);
  220. }
  221. }
  222. } while (swapped == DEF_YES); /* Re-loop until no items have been swapped. */
  223. }