queue.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /*
  2. *
  3. * Copyright (c) 2011, Jue Ruan <ruanjue@gmail.com>
  4. *
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef __FIFO_QUEUE_RJ_H
  20. #define __FIFO_QUEUE_RJ_H
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <stdint.h>
  24. #include <stdio.h>
  25. #include "sort.h"
  26. #include "mem_share.h"
  27. #include "list.h"
  28. #define define_queue_core(list_type, e_type, size_type, inc_size) \
  29. \
  30. typedef struct { e_type* buffer; size_type* links; size_type head, tail, size; size_type* trash; size_type trash_size, trash_cap; size_type off; size_type cap; } list_type; \
  31. \
  32. static inline size_t list_type##_obj_desc_cnt(void *list, int idx){ \
  33. if(idx == 0) return ((list_type*)list)->size * sizeof(e_type); \
  34. else if(idx == 1) return ((list_type*)list)->size * sizeof(size_type); \
  35. else if(idx == 2) return ((list_type*)list)->trash_size * sizeof(size_type); \
  36. else return 1; \
  37. } \
  38. \
  39. static const obj_desc_t list_type##_obj_desc = {.tag = TOSTR(list_type##_obj_desc), .size = sizeof(list_type), .n_child = 3, .addr = {offsetof(list_type, buffer), offsetof(list_type, links), offsetof(list_type, trash)}, .desc = {(struct obj_desc_t*)&OBJ_DESC_DATA, (struct obj_desc_t*)&OBJ_DESC_DATA, (struct obj_desc_t*)&OBJ_DESC_DATA}, .cnt = list_type##_obj_desc_cnt, .post = NULL}; \
  40. \
  41. static inline list_type* init_##list_type(){ \
  42. list_type *list = (list_type*)malloc(sizeof(list_type)); \
  43. list->off = 0; \
  44. list->cap = 0; \
  45. list->buffer = NULL; \
  46. list->links = NULL; \
  47. list->trash = NULL; \
  48. list->trash_size = 0; \
  49. list->trash_cap = 0; \
  50. list->head = 0; \
  51. list->tail = 0; \
  52. list->size = 0; \
  53. return list; \
  54. } \
  55. \
  56. static inline size_type count_##list_type(list_type *list){ return list->size; } \
  57. \
  58. static inline void clear_##list_type(list_type *list){ list->trash_size = 0; list->off = 0; list->head = 0; list->tail = 0; list->size = 0; } \
  59. \
  60. static inline void push_##list_type(list_type *list, e_type e){ \
  61. size_type idx; \
  62. if(list->trash_size){ \
  63. idx = list->trash[--list->trash_size]; \
  64. } else { \
  65. encap_list((void**)&(list->buffer), sizeof(e_type), list->off, list->cap, 1, 0, 0); \
  66. list->cap = encap_list((void**)&(list->links), sizeof(size_type), list->off, list->cap, 1, 0, 0); \
  67. idx = list->off ++; \
  68. } \
  69. list->buffer[idx] = e; \
  70. if(list->size == 0){ \
  71. list->head = list->tail = idx; \
  72. } else { \
  73. list->links[list->tail] = idx; \
  74. } \
  75. list->links[idx] = 0; \
  76. list->tail = idx; \
  77. list->size ++; \
  78. } \
  79. \
  80. static inline int pop_##list_type(list_type *list, e_type*e){ \
  81. if(list->size == 0) return 0; \
  82. *e = list->buffer[list->head]; \
  83. list->trash_cap = encap_list((void**)&list->trash, sizeof(size_type), list->trash_size, list->trash_cap, 1, 0, 0); \
  84. list->trash[list->trash_size ++] = list->head; \
  85. list->head = list->links[list->head]; \
  86. list->size --; \
  87. return 1; \
  88. } \
  89. \
  90. static inline void free_##list_type(list_type *list){ \
  91. if(list->buffer) free(list->buffer); \
  92. if(list->links) free(list->links); \
  93. if(list->trash) free(list->trash); \
  94. free(list); \
  95. }
  96. #define define_queue(name, e_type) define_queue_core(name, e_type, size_t, 0xFFFFFU)
  97. define_queue(u32fifo, uint32_t);
  98. define_queue(s32fifo, int32_t);
  99. define_queue(u64fifo, uint64_t);
  100. define_queue(s64fifo, int64_t);
  101. #endif