mbuf.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /*
  2. * Copyright (c) 2018-2019 Richard Braun.
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. *
  17. * Upstream site with license notes :
  18. * http://git.sceen.net/rbraun/librbraun.git/
  19. *
  20. *
  21. * FIFO message buffer.
  22. */
  23. #ifndef KERN_MBUF_H
  24. #define KERN_MBUF_H
  25. #include <stdbool.h>
  26. #include <stddef.h>
  27. #include <kern/cbuf.h>
  28. /*
  29. * Message buffer.
  30. *
  31. * Message buffers are built on top of circular byte buffers. They provide
  32. * discrete message transfer from a producer to a consumer.
  33. *
  34. * The order is computed from the maximum message size, and is used to
  35. * determine a header size that can represent up to 2^order - 1 bytes.
  36. */
  37. struct mbuf
  38. {
  39. struct cbuf cbuf;
  40. size_t max_msg_size;
  41. unsigned int order;
  42. };
  43. static inline size_t
  44. mbuf_start (const struct mbuf *mbuf)
  45. {
  46. return (cbuf_start (&mbuf->cbuf));
  47. }
  48. static inline size_t
  49. mbuf_end (const struct mbuf *mbuf)
  50. {
  51. return (cbuf_end (&mbuf->cbuf));
  52. }
  53. /*
  54. * Initialize a message buffer.
  55. *
  56. * The descriptor is set to use the given buffer for storage. Capacity
  57. * must be a power-of-two.
  58. */
  59. void mbuf_init (struct mbuf *mbuf, void *buf, size_t capacity,
  60. size_t max_msg_size);
  61. // Clear a message buffer.
  62. void mbuf_clear (struct mbuf *mbuf);
  63. /*
  64. * Push a message to a message buffer.
  65. *
  66. * If the message doesn't fit in the message buffer, either because it is
  67. * larger than the capacity, or because the function isn't allowed to erase
  68. * old messages and the message buffer doesn't have enough available memory
  69. * for the new message, EMSGSIZE is returned. If the message is larger than
  70. * the maximum message size, EINVAL is returned.
  71. */
  72. int mbuf_push (struct mbuf *mbuf, const void *buf, size_t size, bool erase);
  73. /*
  74. * Pop a message from a message buffer.
  75. *
  76. * On entry, the sizep argument points to the size of the output buffer.
  77. * On return, it is updated to the size of the message. If the message
  78. * doesn't fit in the output buffer, it is not popped, EMSGSIZE is
  79. * returned, but the sizep argument is updated nonetheless to let the
  80. * user know the message size, to potentially retry with a larger buffer.
  81. *
  82. * If the buffer is empty, EAGAIN is returned, and the size of the output
  83. * buffer is unmodified.
  84. *
  85. * The output buffer may be NULL, in which case this function acts as if
  86. * it wasn't, but without writing output data.
  87. */
  88. int mbuf_pop (struct mbuf *mbuf, void *buf, size_t *sizep);
  89. /*
  90. * Read a message from a message buffer.
  91. *
  92. * On entry, the indexp argument points to the index of the message to
  93. * read in the message buffer, and the sizep argument points to the size
  94. * of the output buffer. On return, if successful, indexp is updated
  95. * to the index of the next message, and sizep to the size of the
  96. * message read.
  97. *
  98. * If the message doesn't fit in the output buffer, it is not read,
  99. * EMSGSIZE is returned, and the sizep argument is updated nonetheless
  100. * to let the user know the message size, to potentially retry with a
  101. * larger buffer.
  102. *
  103. * If the given index refers to the end of the buffer, then EAGAIN is
  104. * returned. If it's outside buffer boundaries, EINVAL is returned.
  105. * Otherwise, if it doesn't point to the beginning of a message, the
  106. * behavior is undefined.
  107. *
  108. * The message buffer isn't changed by this operation.
  109. */
  110. int mbuf_read (const struct mbuf *mbuf, size_t *indexp,
  111. void *buf, size_t *sizep);
  112. #endif