rbuf_pool.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*******************************************************************************
  2. * @file rbuf_pool.c
  3. * @author MEMS Application Team
  4. * @version V1.0
  5. * @date 2020-10-15
  6. * @brief ring buffer pool for interaction RAM
  7. *******************************************************************************/
  8. /******************************************************************************/
  9. //includes
  10. /******************************************************************************/
  11. #include <string.h>
  12. #include <stdio.h>
  13. #include <rbuf/rbuf_pool.h>
  14. /******************************************************************************/
  15. //constants
  16. /******************************************************************************/
  17. /******************************************************************************/
  18. //typedef
  19. /******************************************************************************/
  20. /******************************************************************************/
  21. //variables
  22. /******************************************************************************/
  23. /******************************************************************************/
  24. //functions
  25. /******************************************************************************/
  26. static rbuf_node_t *_pool_alloc_node(rbuf_pool_t *pool, unsigned int size)
  27. {
  28. rbuf_node_t *node = RBUF_NULL;
  29. if (pool->buf_size >= sizeof(rbuf_node_t)) {
  30. /* alloc from free buffer */
  31. node = (rbuf_node_t*)RBUF_FR_OF(pool->buf_off);
  32. node->blk_list = 0;
  33. node->blk_size = size;
  34. node->next = 0;
  35. /* update free buffer */
  36. pool->buf_off += sizeof(rbuf_node_t);
  37. pool->buf_size -= sizeof(rbuf_node_t);
  38. }
  39. return node;
  40. }
  41. static rbuf_node_t *_pool_get_node(rbuf_pool_t *pool, unsigned int size)
  42. {
  43. rbuf_node_t *node = &pool->root;
  44. rbuf_node_t *prev = NULL;
  45. /* node search */
  46. while ((node != RBUF_NULL) && (node->blk_size < size)) {
  47. prev = node;
  48. node = (rbuf_node_t*)RBUF_FR_OF(node->next);
  49. }
  50. /* add node to list */
  51. if ((node == RBUF_NULL) || (node->blk_size > size)) {
  52. node = _pool_alloc_node(pool, size);
  53. if (node != RBUF_NULL) {
  54. node->next = prev->next;
  55. prev->next = RBUF_TO_OF(node);
  56. }
  57. }
  58. return node;
  59. }
  60. rbuf_pool_t *rbuf_pool_init(char *buf, unsigned int size)
  61. {
  62. rbuf_pool_t *pool = (rbuf_pool_t*)buf;
  63. pool->buf_off = RBUF_TO_OF(buf) + sizeof(rbuf_pool_t);
  64. pool->buf_size = size - sizeof(rbuf_pool_t);
  65. pool->root.blk_size = 0;
  66. pool->root.blk_list = 0;
  67. pool->root.next = 0;
  68. return pool;
  69. }
  70. rbuf_t *rbuf_pool_alloc(rbuf_pool_t *pool, unsigned int size, unsigned int mode)
  71. {
  72. rbuf_node_t *node;
  73. rbuf_t *buf = NULL;
  74. unsigned int buf_size;
  75. /* get node */
  76. size = ROUND_UP(size, 4);
  77. node = _pool_get_node(pool, size);
  78. if (node == RBUF_NULL) {
  79. return NULL;
  80. }
  81. /* alloc rbuf */
  82. while (node != RBUF_NULL) {
  83. buf_size = sizeof(rbuf_t) + node->blk_size;
  84. if (node->blk_list > 0) {
  85. /* alloc from free blk list */
  86. buf = RBUF_FR_OF(node->blk_list);
  87. node->blk_list = buf->next;
  88. break;
  89. }
  90. if (pool->buf_size >= buf_size) {
  91. /* alloc from free buffer */
  92. buf = RBUF_FR_OF(pool->buf_off);
  93. pool->buf_off += buf_size;
  94. pool->buf_size -= buf_size;
  95. break;
  96. }
  97. node = (rbuf_node_t*)RBUF_FR_OF(node->next);
  98. }
  99. /* init rbuf */
  100. if (buf != NULL) {
  101. rbuf_init_buf((char*)buf, buf_size, mode);
  102. buf->next = RBUF_TO_OF(node);
  103. }
  104. return buf;
  105. }
  106. int rbuf_pool_free(rbuf_t *buf)
  107. {
  108. rbuf_node_t *node;
  109. if (buf->next != 0) {
  110. node = (rbuf_node_t*)RBUF_FR_OF(buf->next);
  111. /* free to free blk list */
  112. buf->next = node->blk_list;
  113. node->blk_list = RBUF_TO_OF(buf);
  114. }
  115. return 0;
  116. }
  117. #if RBUF_POOL_DBG
  118. void rbuf_pool_dump(rbuf_pool_t *pool)
  119. {
  120. rbuf_node_t *node = &pool->root;
  121. rbuf_t *buf;
  122. /* dump free */
  123. printf("free: [0x%04x] [%d]\r\n", (unsigned int)pool->buf_off, pool->buf_size);
  124. printf("\r\n");
  125. while (node != RBUF_NULL) {
  126. /* dump node */
  127. printf("node: [0x%04x] [%d]\r\n", RBUF_TO_OF(node), node->blk_size);
  128. /* dump list */
  129. buf = RBUF_FR_OF(node->blk_list);
  130. while (buf != RBUF_NULL) {
  131. printf(" -> rbuf: [0x%04x] [%d] [%d]\r\n", RBUF_TO_OF(buf), buf->size, buf->hlen);
  132. buf = RBUF_FR_OF(buf->next);
  133. }
  134. node = (rbuf_node_t*)RBUF_FR_OF(node->next);
  135. }
  136. printf("\r\n");
  137. }
  138. #endif