acts_ringbuf.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. /*
  2. * Copyright (c) 1997-2015, Actions Semi Co., Inc.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #ifndef __ACTS_RINGBUF_H__
  7. #define __ACTS_RINGBUF_H__
  8. #include <stddef.h>
  9. #include <stdint.h>
  10. #include <errno.h>
  11. #include <sys/types.h>
  12. #include <sys/util.h>
  13. #include <mem_manager.h>
  14. #ifdef __cplusplus
  15. extern "C" {
  16. #endif
  17. #ifndef SIZE32_OF
  18. # define SIZE32_OF(x) (sizeof((x)) / sizeof(uint32_t))
  19. #endif
  20. #ifndef SIZE16_OF
  21. # define SIZE16_OF(x) (sizeof((x)) / sizeof(uint16_t))
  22. #endif
  23. #ifndef SIZE8_OF
  24. # define SIZE8_OF(x) (sizeof((x)))
  25. #endif
  26. #ifndef IS_POWER_OF_TWO
  27. # define IS_POWER_OF_TWO(x) ((x) && !((x) & ((x) - 1)))
  28. #endif
  29. /* get #of elements in a static array */
  30. #ifndef NELEM
  31. # define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
  32. #endif
  33. /* actions ring buffer element size in bytes */
  34. #define ACTS_RINGBUF_ELEMSZ (1)
  35. #define ACTS_RINGBUF_NELEM(size8) ((size8) / ACTS_RINGBUF_ELEMSZ)
  36. #define ACTS_RINGBUF_SIZE8(n) ((n) * ACTS_RINGBUF_ELEMSZ)
  37. #define min_t(type, x, y) ({ \
  38. type __min1 = (x); \
  39. type __min2 = (y); \
  40. __min1 < __min2 ? __min1 : __min2; })
  41. #define max_t(type, x, y) ({ \
  42. type __max1 = (x); \
  43. type __max2 = (y); \
  44. __max1 > __max2 ? __max1 : __max2; })
  45. typedef int (*acts_ringbuf_read_fn)(void *, void *, unsigned int);
  46. typedef int (*acts_ringbuf_write_fn)(void *, const void *, unsigned int);
  47. struct acts_ringbuf {
  48. /* Index in buf for the head element */
  49. uint32_t head;
  50. /* Index in buf for the tail element */
  51. uint32_t tail;
  52. /* Size of buffer in elements */
  53. uint32_t size;
  54. /* Modulo mask if size is a power of 2 */
  55. uint32_t mask;
  56. /* cpu/dsp address of buffer */
  57. uint32_t cpu_ptr; /* in bytes */
  58. uint32_t dsp_ptr; /* in 16-bit words */
  59. /* Index in actual buf for the head element */
  60. uint32_t head_offset;
  61. /* Index in actual buf for the tail element */
  62. uint32_t tail_offset;
  63. };
  64. /**
  65. * @brief Statically define and initialize a high performance ring buffer.
  66. *
  67. * This macro establishes a ring buffer whose size must be a power of 2;
  68. * that is, the ring buffer contains 2^pow 32-bit words, where @a pow is
  69. * the specified ring buffer size exponent. A high performance ring buffer
  70. * doesn't require the use of modulo arithmetic operations to maintain itself.
  71. *
  72. * This ring buffer defined in this way can only be accessed on cpu side.
  73. *
  74. * The ring buffer can be accessed outside the module where it is defined
  75. * using:
  76. *
  77. * @code extern struct acts_ringbuf <name>; @endcode
  78. *
  79. * @param name Name of the ring buffer.
  80. * @param buf Ring buffer data area.
  81. * @param pow Ring buffer size exponent in elements.
  82. */
  83. #define ACTS_RINGBUF_DEFINE_POW2(name, buf, pow) \
  84. struct acts_ringbuf name = { \
  85. .head = 0, \
  86. .head_offset = 0, \
  87. .tail = 0, \
  88. .tail_offset = 0, \
  89. .mask = (1u << (pow)) - 1, \
  90. .size = 1u << (pow), \
  91. .cpu_ptr = (uint32_t)buf, \
  92. .dsp_ptr = UINT32_MAX, \
  93. }
  94. /**
  95. * @brief Statically define and initialize a standard ring buffer.
  96. *
  97. * This macro establishes a ring buffer of an arbitrary size. A standard
  98. * ring buffer uses modulo arithmetic operations to maintain itself.
  99. *
  100. * This ring buffer defined in this way can only be accessed on cpu side.
  101. *
  102. * The ring buffer can be accessed outside the module where it is defined
  103. * using:
  104. *
  105. * @code extern struct acts_ringbuf <name>; @endcode
  106. *
  107. * @param name Name of the ring buffer.
  108. * @param buf Ring buffer data area.
  109. * @param size_e Ring buffer size in elements.
  110. */
  111. #define ACTS_RINGBUF_DEFINE(name, buf, size_e) \
  112. struct acts_ringbuf name = { \
  113. .head = 0, \
  114. .head_offset = 0, \
  115. .tail = 0, \
  116. .tail_offset = 0, \
  117. .mask = IS_POWER_OF_TWO(size_e) ? (size_e - 1) : 0, \
  118. .size = size_e, \
  119. .cpu_ptr = (uint32_t)buf, \
  120. .dsp_ptr = UINT32_MAX, \
  121. }
  122. /**
  123. * @brief Initialize a ring buffer.
  124. *
  125. * This routine initializes a ring buffer, prior to its first use.
  126. *
  127. * Setting @a size to a power of 2 establishes a high performance ring buffer
  128. * that doesn't require the use of modulo arithmetic operations to maintain
  129. * itself.
  130. *
  131. * @param buf Address of ring buffer.
  132. * @param data Ring buffer data area.
  133. * @param size Ring buffer size in elements.
  134. *
  135. * @return 0 if succeed, or 0 if not.
  136. */
  137. int acts_ringbuf_init(struct acts_ringbuf *buf, void *data, uint32_t size);
  138. /**
  139. * @brief ALLocate a ringbuf structure and initialize it.
  140. *
  141. * This routine allocate a ring buffer structure and initialize it,
  142. * prior to its first use.
  143. *
  144. * Setting @a size to a power of 2 establishes a high performance ring buffer
  145. * that doesn't require the use of modulo arithmetic operations to maintain
  146. * itself.
  147. *
  148. * @param data Ring buffer data area.
  149. * @param size Ring buffer size in elements.
  150. *
  151. * @return Ring buffer.
  152. */
  153. struct acts_ringbuf *acts_ringbuf_init_ext(void *data, uint32_t size);
  154. /**
  155. * @brief Destroy a ringbuf.
  156. *
  157. * This routine destroy a ring buffer initialized by acts_ringbuf_init_ext.
  158. *
  159. * @param buf Address of ring buffer.
  160. *
  161. * @return N/A.
  162. */
  163. void acts_ringbuf_destroy_ext(struct acts_ringbuf *buf);
  164. /**
  165. * @brief Allocate a ring buffer.
  166. *
  167. * This routine allocate a ring buffer.
  168. *
  169. * Setting @a size to a power of 2 establishes a high performance ring buffer
  170. * that doesn't require the use of modulo arithmetic operations to maintain
  171. * itself.
  172. *
  173. * @param size Ring buffer size in elements.
  174. *
  175. * @return Ring buffer.
  176. */
  177. struct acts_ringbuf *acts_ringbuf_alloc(uint32_t size);
  178. /**
  179. * @brief Free a ring buffer.
  180. *
  181. * This routine free a ring buffer allocated by acts_ringbuf_alloc.
  182. *
  183. * @param buf Address of ring buffer.
  184. *
  185. * @return N/A.
  186. */
  187. void acts_ringbuf_free(struct acts_ringbuf *buf);
  188. /**
  189. * @brief Peek a ring buffer.
  190. *
  191. * This routine peek a ring buffer.
  192. *
  193. * @param buf Address of ring buffer.
  194. * @param data Address of data.
  195. * @param size Size of data in elements.
  196. *
  197. * @return number of elements successfully peek.
  198. */
  199. uint32_t acts_ringbuf_peek(struct acts_ringbuf *buf, void *data, uint32_t size);
  200. /**
  201. * @brief Read a ring buffer.
  202. *
  203. * This routine read a ring buffer.
  204. *
  205. * @param buf Address of ring buffer.
  206. * @param data Address of data.
  207. * @param size Size of data in elements.
  208. *
  209. * @return number of elements successfully read.
  210. */
  211. uint32_t acts_ringbuf_get(struct acts_ringbuf *buf, void *data, uint32_t size);
  212. /**
  213. * @brief Get address of a valid data in a ring buffer.
  214. *
  215. * With this routine, memory copying can be reduced since internal ring buffer
  216. * can be used directly by the user. Once data is processed it can be freed
  217. * using @ref acts_ringbuf_get_finish.
  218. *
  219. * @param[in] buf Address of ring buffer.
  220. * @param[out] data Pointer to the address. It is set to a location within
  221. * ring buffer.
  222. * @param[in] size Requested size in elements.
  223. *
  224. * @return Number of valid elements in the provided buffer which can be smaller
  225. * than requested if there is not enough free space or buffer wraps.
  226. */
  227. uint32_t acts_ringbuf_get_claim(struct acts_ringbuf *buf, void **data, uint32_t size);
  228. /**
  229. * @brief Indicate number of elements read from claimed buffer.
  230. *
  231. * @param buf Address of ring buffer.
  232. * @param size Number of elements that can be freed.
  233. *
  234. * @retval 0 Successful operation.
  235. * @retval -EINVAL Provided @a size exceeds valid elements in the ring buffer.
  236. */
  237. int acts_ringbuf_get_finish(struct acts_ringbuf *buf, uint32_t size);
  238. /**
  239. * @brief Write a ring buffer.
  240. *
  241. * This routine write a ring buffer.
  242. *
  243. * @param buf Address of ring buffer.
  244. * @param data Address of data.
  245. * @param size Size of data in elements.
  246. *
  247. * @return number of elements successfully written.
  248. */
  249. uint32_t acts_ringbuf_put(struct acts_ringbuf *buf, const void *data, uint32_t size);
  250. /**
  251. * @brief Allocate buffer for writing data to a ring buffer.
  252. *
  253. * With this routine, memory copying can be reduced since internal ring buffer
  254. * can be used directly by the user. Once data is written to allocated area
  255. * number of bytes written can be confirmed (see @ref acts_ringbuf_put_finish).
  256. *
  257. * @param[in] buf Address of ring buffer.
  258. * @param[out] data Pointer to the address. It is set to a location within
  259. * ring buffer.
  260. * @param[in] size Requested allocation size in elements.
  261. *
  262. * @return Size of allocated buffer which can be smaller than requested if
  263. * there is not enough free space or buffer wraps.
  264. */
  265. uint32_t acts_ringbuf_put_claim(struct acts_ringbuf *buf, void **data, uint32_t size);
  266. /**
  267. * @brief Indicate number of elements written to allocated buffers.
  268. *
  269. * @warning
  270. * Use cases involving multiple writers to the ring buffer must prevent
  271. * concurrent write operations, either by preventing all writers from
  272. * being preempted or by using a mutex to govern writes to the ring buffer.
  273. *
  274. * @warning
  275. * Ring buffer instance should not mix byte access and item access
  276. * (calls prefixed with ring_buf_item_).
  277. *
  278. * @param buf Address of ring buffer.
  279. * @param size Number of valid elements in the allocated buffers.
  280. *
  281. * @retval 0 Successful operation.
  282. * @retval -EINVAL Provided @a size exceeds free space in the ring buffer.
  283. */
  284. int acts_ringbuf_put_finish(struct acts_ringbuf *buf, uint32_t size);
  285. /**
  286. * @brief Copy a ring buffer.
  287. *
  288. * This routine copy a ring buffer.
  289. *
  290. * @param dst_buf Address of destination ring buffer.
  291. * @param src_buf Address of source ring buffer.
  292. * @param size Size of data in elements.
  293. *
  294. * @return number of elements successfully copied.
  295. */
  296. uint32_t acts_ringbuf_copy(struct acts_ringbuf *dst_buf, struct acts_ringbuf *src_buf, uint32_t size);
  297. /**
  298. * @brief Read a ring buffer to stream.
  299. *
  300. * This routine read a ring buffer.
  301. *
  302. * @param buf Address of ring buffer.
  303. * @param stream Handle of stream.
  304. * @param size Size of data in elements.
  305. * @param stream_write Stream write ops.
  306. *
  307. * @return number of elements successfully read.
  308. */
  309. uint32_t acts_ringbuf_read(struct acts_ringbuf *buf,
  310. void *stream, uint32_t size, acts_ringbuf_write_fn stream_write);
  311. /**
  312. * @brief Read a ring buffer to stream.
  313. *
  314. * This routine read a ring buffer.
  315. *
  316. * @param buf Address of ring buffer.
  317. * @param stream Handle of stream.
  318. * @param size Size of data in elements.
  319. * @param stream_read Stream read ops.
  320. *
  321. * @return number of elements successfully read.
  322. */
  323. uint32_t acts_ringbuf_write(struct acts_ringbuf *buf,
  324. void *stream, uint32_t size, acts_ringbuf_read_fn stream_read);
  325. /**
  326. * @brief Determine size of a ring buffer.
  327. *
  328. * @param buf Address of ring buffer.
  329. *
  330. * @return Ring buffer size in elements.
  331. */
  332. static inline uint32_t acts_ringbuf_size(struct acts_ringbuf *buf)
  333. {
  334. return buf->size;
  335. }
  336. /**
  337. * @brief Determine data length in a ring buffer.
  338. *
  339. * @param buf Address of ring buffer.
  340. *
  341. * @return Ring buffer data length in elements.
  342. */
  343. static inline uint32_t acts_ringbuf_length(struct acts_ringbuf *buf)
  344. {
  345. return buf->tail - buf->head;
  346. }
  347. /**
  348. * @brief Determine free space in a ring buffer.
  349. *
  350. * @param buf Address of ring buffer.
  351. *
  352. * @return Ring buffer free space in elements.
  353. */
  354. static inline uint32_t acts_ringbuf_space(struct acts_ringbuf *buf)
  355. {
  356. return buf->size - (buf->tail - buf->head);
  357. }
  358. /**
  359. * @brief Determine if a ring buffer is empty.
  360. *
  361. * @param buf Address of ring buffer.
  362. *
  363. * @return 1 if the ring buffer is empty, or 0 if not.
  364. */
  365. static inline int acts_ringbuf_is_empty(struct acts_ringbuf *buf)
  366. {
  367. return buf->head == buf->tail;
  368. }
  369. /**
  370. * @brief Determine if a ring buffer is full.
  371. *
  372. * @param buf Address of ring buffer.
  373. *
  374. * @return 1 if the ring buffer is full, or 0 if not.
  375. */
  376. static inline int acts_ringbuf_is_full(struct acts_ringbuf *buf)
  377. {
  378. return buf->size == (buf->tail - buf->head);
  379. }
  380. /**
  381. * @brief Determine if a ring buffer is empty.
  382. *
  383. * @param buf Address of ring buffer.
  384. *
  385. * @return 1 if the ring buffer is more than half empty, or 0 if not.
  386. */
  387. static inline int acts_ringbuf_is_half_empty(struct acts_ringbuf *buf)
  388. {
  389. return (buf->tail - buf->head) <= (buf->size >> 1);
  390. }
  391. /**
  392. * @brief Determine if a ring buffer is full.
  393. *
  394. * @param buf Address of ring buffer.
  395. *
  396. * @return 1 if the ring buffer is more than half full, or 0 if not.
  397. */
  398. static inline int acts_ringbuf_is_half_full(struct acts_ringbuf *buf)
  399. {
  400. return (buf->tail - buf->head) >= (buf->size >> 1);
  401. }
  402. /**
  403. * @brief Reset a ring buffer
  404. *
  405. * @param buf Address of ring buffer.
  406. *
  407. * @return N/A
  408. */
  409. static inline void acts_ringbuf_reset(struct acts_ringbuf *buf)
  410. {
  411. buf->head = buf->head_offset = buf->tail = buf->tail_offset = 0;
  412. }
  413. /**
  414. * @brief Drop data of a ring buffer
  415. *
  416. * @param buf Address of ring buffer.
  417. * @param size Size of data in elements.
  418. *
  419. * @return number of elements dropped in elements.
  420. */
  421. uint32_t acts_ringbuf_drop(struct acts_ringbuf *buf, uint32_t size);
  422. /**
  423. * @brief Drop all data of a ring buffer
  424. *
  425. * @param buf Address of ring buffer.
  426. *
  427. * @return number of elements dropped in elements.
  428. */
  429. uint32_t acts_ringbuf_drop_all(struct acts_ringbuf *buf);
  430. /**
  431. * @brief Fill constant data of a ring buffer.
  432. *
  433. * @param buf Address of ring buffer.
  434. * @param size Size of data in elements.
  435. *
  436. * @return number of elements filled.
  437. */
  438. uint32_t acts_ringbuf_fill(struct acts_ringbuf *buf, uint8_t c, uint32_t size);
  439. /**
  440. * @brief Fill no data of a ring buffer.
  441. *
  442. * @param buf Address of ring buffer.
  443. * @param size Size of data in elements.
  444. *
  445. * @return number of elements filled.
  446. */
  447. uint32_t acts_ringbuf_fill_none(struct acts_ringbuf *buf, uint32_t size);
  448. /**
  449. * @brief Determine the internal buffer head offset of a ring buffer
  450. *
  451. * @param buf Address of ring buffer.
  452. *
  453. * @return the head offset of ring buffer.
  454. */
  455. static inline int acts_ringbuf_head_offset(struct acts_ringbuf *buf)
  456. {
  457. return buf->head_offset;
  458. }
  459. /**
  460. * @brief Determine the internal buffer head pointer of a ring buffer
  461. *
  462. * @param[in] buf Address of ring buffer.
  463. * @param[out] len store the number of contiguous accessable elements
  464. * started from head
  465. *
  466. * @return the head pointer of ring buffer.
  467. */
  468. void *acts_ringbuf_head_ptr(struct acts_ringbuf *buf, uint32_t *len);
  469. /**
  470. * @brief Determine the internal buffer tail pointer of a ring buffer
  471. *
  472. * @param[in] buf Address of ring buffer.
  473. * @param[out] len store number of contiguous accessable elements
  474. * started from tail
  475. *
  476. * @return the tail pointer of ring buffer.
  477. */
  478. void *acts_ringbuf_tail_ptr(struct acts_ringbuf *buf, uint32_t *len);
  479. /**
  480. * @brief Determine the internal buffer tail offset of a ring buffer
  481. *
  482. * @param buf Address of ring buffer.
  483. *
  484. * @return the tail offset of ring buffer.
  485. */
  486. static inline int acts_ringbuf_tail_offset(struct acts_ringbuf *buf)
  487. {
  488. return buf->tail_offset;
  489. }
  490. /**
  491. * @brief Defrag a ring buffer.
  492. *
  493. * This can help ring buffer to simulate a line buffer.
  494. *
  495. * @param buf Address of ring buffer.
  496. *
  497. * @return N/A
  498. */
  499. void acts_ringbuf_defrag(struct acts_ringbuf *buf);
  500. /**
  501. * @brief Dump information of a ring buffer
  502. *
  503. * @param buf Address of ring buffer.
  504. * @param name Name of ring buffer.
  505. * @param line_prefix Prefix of each line.
  506. *
  507. * @return N/A
  508. */
  509. void acts_ringbuf_dump(struct acts_ringbuf *buf, const char *name, const char *line_prefix);
  510. #ifdef __cplusplus
  511. }
  512. #endif
  513. #endif /* __ACTS_RINGBUF_H__ */