Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 

252 righe
5.8 KiB

  1. /*
  2. * Lua RTOS, list data structure
  3. *
  4. * Copyright (C) 2015 - 2017
  5. * IBEROXARXA SERVICIOS INTEGRALES, S.L. & CSS IBÉRICA, S.L.
  6. *
  7. * Author: Jaume Olivé (jolive@iberoxarxa.com / jolive@whitecatboard.org)
  8. *
  9. * All rights reserved.
  10. *
  11. * Permission to use, copy, modify, and distribute this software
  12. * and its documentation for any purpose and without fee is hereby
  13. * granted, provided that the above copyright notice appear in all
  14. * copies and that both that the copyright notice and this
  15. * permission notice and warranty disclaimer appear in supporting
  16. * documentation, and that the name of the author not be used in
  17. * advertising or publicity pertaining to distribution of the
  18. * software without specific, written prior permission.
  19. *
  20. * The author disclaim all warranties with regard to this
  21. * software, including all implied warranties of merchantability
  22. * and fitness. In no event shall the author be liable for any
  23. * special, indirect or consequential damages or any damages
  24. * whatsoever resulting from loss of use, data or profits, whether
  25. * in an action of contract, negligence or other tortious action,
  26. * arising out of or in connection with the use or performance of
  27. * this software.
  28. */
  29. #include "esp_attr.h"
  30. #include <errno.h>
  31. #include <string.h>
  32. #include <stdlib.h>
  33. #include "list.h"
  34. #include "mutex.h"
  35. void list_init(struct list *list, int first_index) {
  36. // Create the mutex
  37. mtx_init(&list->mutex, NULL, NULL, 0);
  38. mtx_lock(&list->mutex);
  39. list->indexes = 0;
  40. list->free = NULL;
  41. list->index = NULL;
  42. list->first_index = first_index;
  43. mtx_unlock(&list->mutex);
  44. }
  45. int list_add(struct list *list, void *item, int *item_index) {
  46. struct list_index *index = NULL;
  47. struct list_index *indexa = NULL;
  48. int grow = 0;
  49. mtx_lock(&list->mutex);
  50. // Get an index
  51. if (list->free) {
  52. // Get first free element
  53. index = list->free;
  54. list->free = index->next;
  55. } else {
  56. // Must grow index array
  57. grow = 1;
  58. }
  59. if (grow) {
  60. // Increment index count
  61. list->indexes++;
  62. // Create a new index array for allocate new index
  63. indexa = (struct list_index *)malloc(sizeof(struct list_index) * list->indexes);
  64. if (!indexa) {
  65. mtx_unlock(&list->mutex);
  66. return ENOMEM;
  67. }
  68. if (list->index) {
  69. // Copy current index array to new created
  70. bcopy(list->index, indexa, sizeof(struct list_index) * (list->indexes - 1));
  71. // Free current index array
  72. free(list->index);
  73. }
  74. // Store new index array
  75. list->index = indexa;
  76. // Current index
  77. index = list->index + list->indexes - 1;
  78. // Initialize new index
  79. index->index = list->indexes - 1;
  80. }
  81. index->next = NULL;
  82. index->item = item;
  83. index->deleted = 0;
  84. // Return index
  85. *item_index = index->index + list->first_index;
  86. mtx_unlock(&list->mutex);
  87. return 0;
  88. }
  89. int IRAM_ATTR list_get(struct list *list, int index, void **item) {
  90. struct list_index *cindex = NULL;
  91. int iindex;
  92. mtx_lock(&list->mutex);
  93. if (!list->indexes) {
  94. mtx_unlock(&list->mutex);
  95. return EINVAL;
  96. }
  97. // Check index
  98. if (index < list->first_index) {
  99. mtx_unlock(&list->mutex);
  100. return EINVAL;
  101. }
  102. // Get new internal index
  103. iindex = index - list->first_index;
  104. // Test for a valid index
  105. if (iindex > list->indexes) {
  106. mtx_unlock(&list->mutex);
  107. return EINVAL;
  108. }
  109. cindex = list->index + iindex;
  110. if (cindex->deleted) {
  111. mtx_unlock(&list->mutex);
  112. return EINVAL;
  113. }
  114. *item = cindex->item;
  115. mtx_unlock(&list->mutex);
  116. return 0;
  117. }
  118. int list_remove(struct list *list, int index, int destroy) {
  119. struct list_index *cindex = NULL;
  120. int iindex;
  121. mtx_lock(&list->mutex);
  122. // Check index
  123. if (index < list->first_index) {
  124. mtx_unlock(&list->mutex);
  125. return EINVAL;
  126. }
  127. // Get new internal index
  128. iindex = index - list->first_index;
  129. // Test for a valid index
  130. if ((iindex < 0) || (iindex > list->indexes)) {
  131. mtx_unlock(&list->mutex);
  132. return EINVAL;
  133. }
  134. cindex = &list->index[iindex];
  135. if (destroy) {
  136. free(cindex->item);
  137. }
  138. cindex->next = list->free;
  139. cindex->deleted = 1;
  140. list->free = cindex;
  141. mtx_unlock(&list->mutex);
  142. return 0;
  143. }
  144. int IRAM_ATTR list_first(struct list *list) {
  145. int index;
  146. int res = -1;
  147. mtx_lock(&list->mutex);
  148. for(index=0;index < list->indexes;index++) {
  149. if (!list->index[index].deleted) {
  150. res = index + list->first_index;
  151. break;
  152. }
  153. }
  154. mtx_unlock(&list->mutex);
  155. return res;
  156. }
  157. int IRAM_ATTR list_next(struct list *list, int index) {
  158. int res = -1;
  159. int iindex;
  160. mtx_lock(&list->mutex);
  161. // Check index
  162. if (index < list->first_index) {
  163. mtx_unlock(&list->mutex);
  164. return -1;
  165. }
  166. // Get new internal index
  167. iindex = index - list->first_index + 1;
  168. // Get next non deleted item on list
  169. for(;iindex < list->indexes;iindex++) {
  170. if (!list->index[iindex].deleted) {
  171. res = iindex + list->first_index;
  172. break;
  173. }
  174. }
  175. mtx_unlock(&list->mutex);
  176. return res;
  177. }
  178. void list_destroy(struct list *list, int items) {
  179. int index;
  180. mtx_lock(&list->mutex);
  181. if (items) {
  182. for(index=0;index < list->indexes;index++) {
  183. if (!list->index[index].deleted) {
  184. free(list->index[index].item);
  185. }
  186. }
  187. }
  188. free(list->index);
  189. mtx_unlock(&list->mutex);
  190. mtx_destroy(&list->mutex);
  191. }