PatchworkOS  dbbdc99
A non-POSIX operating system.
Loading...
Searching...
No Matches
fifo.h
Go to the documentation of this file.
1#pragma once
2
3#include <errno.h>
4#include <stdint.h>
5#include <string.h>
6
7/**
8 * @brief First-in first-out buffer.
9 * @defgroup kernel_utils_fifo FIFO Buffer
10 * @ingroup kernel_utils
11 *
12 * @{
13 */
14
15/**
16 * @brief FIFO Buffer.
17 * @struct fifo_t
18 */
19typedef struct fifo
20{
21 uint8_t* buffer; ///< Pointer to the buffer memory.
22 size_t size; ///< The total size of the buffer.
23 size_t head; ///< The position to write to.
24 size_t tail; ///< The position to start reading from.
25} fifo_t;
26
27/**
28 * @brief Create a fifo buffer initializer.
29 *
30 * @param _buf Pointer to the buffer memory.
31 * @param _size The size of the buffer in bytes.
32 */
33#define FIFO_CREATE(_buf, _size) {.buffer = (uint8_t*)(_buf), .size = (_size), .head = 0, .tail = 0}
34
35/**
36 * @brief Define and initialize a fifo buffer.
37 *
38 * Helps define a fifo buffer with a backing buffer.
39 *
40 * @param _name The name of the fifo buffer.
41 * @param _size The size of the fifo buffer in bytes.
42 */
43#define FIFO_DEFINE(_name, _size) \
44 uint8_t _name##_buffer[_size]; \
45 fifo_t _name = FIFO_CREATE(_name##_buffer, _size)
46
47/**
48 * @brief Initialize a fifo buffer.
49 *
50 * @param fifo Pointer to the fifo buffer structure.
51 * @param buffer Pointer to the buffer memory.
52 * @param size The size of the buffer in bytes.
53 */
54static inline void fifo_init(fifo_t* fifo, uint8_t* buffer, size_t size)
55{
56 fifo->buffer = buffer;
57 fifo->size = size;
58 fifo->head = 0;
59 fifo->tail = 0;
60}
61
62/**
63 * @brief Reset a fifo buffer.
64 *
65 * @param fifo Pointer to the fifo buffer structure.
66 */
67static inline void fifo_reset(fifo_t* fifo)
68{
69 fifo->head = 0;
70 fifo->tail = 0;
71}
72
73/**
74 * @brief Return the number of bytes available for reading in a fifo buffer.
75 *
76 * @param fifo Pointer to the fifo buffer structure.
77 * @return The number of bytes used.
78 */
79static inline size_t fifo_bytes_readable(const fifo_t* fifo)
80{
81 if (fifo->head >= fifo->tail)
82 {
83 return fifo->head - fifo->tail;
84 }
85
86 return fifo->size - (fifo->tail - fifo->head);
87}
88
89/**
90 * @brief Return the number of bytes available for writing in a fifo buffer.
91 *
92 * @param fifo Pointer to the fifo buffer structure.
93 * @return The number of bytes available for writing.
94 */
95static inline size_t fifo_bytes_writeable(const fifo_t* fifo)
96{
97 if (fifo->tail > fifo->head)
98 {
99 return fifo->tail - fifo->head - 1;
100 }
101
102 return fifo->size - (fifo->head - fifo->tail) - 1;
103}
104
105/**
106 * @brief Read data from a fifo buffer at a specific offset.
107 *
108 * @param fifo The fifo buffer structure.
109 * @param buffer The destination buffer.
110 * @param count The number of bytes to read.
111 * @return The number of bytes read.
112 */
113static inline size_t fifo_read(fifo_t* fifo, void* buffer, size_t count)
114{
115 size_t readable = fifo_bytes_readable(fifo);
116 if (readable == 0)
117 {
118 return 0;
119 }
120
121 if (count > readable)
122 {
123 count = readable;
124 }
125
126 size_t firstSize = fifo->size - fifo->tail;
127 if (firstSize > count)
128 {
129 firstSize = count;
130 }
131
132 memcpy(buffer, fifo->buffer + fifo->tail, firstSize);
133 fifo->tail = (fifo->tail + firstSize) % fifo->size;
134
135 size_t remaining = count - firstSize;
136 if (remaining > 0)
137 {
138 memcpy((uint8_t*)buffer + firstSize, fifo->buffer + fifo->tail, remaining);
139 fifo->tail = (fifo->tail + remaining) % fifo->size;
140 }
141
142 return count;
143}
144
145/**
146 * @brief Write data to the fifo buffer.
147 *
148 * Will write up to the available space.
149 *
150 * @param fifo Pointer to the fifo buffer structure.
151 * @param buffer The source buffer.
152 * @param count The number of bytes to write.
153 * @return The number of bytes written.
154 */
155static inline size_t fifo_write(fifo_t* fifo, const void* buffer, size_t count)
156{
157 size_t writeable = fifo_bytes_writeable(fifo);
158 if (count > writeable)
159 {
160 count = writeable;
161 }
162
163 size_t firstSize = fifo->size - fifo->head;
164 if (firstSize > count)
165 {
166 firstSize = count;
167 }
168
169 memcpy(fifo->buffer + fifo->head, buffer, firstSize);
170 fifo->head = (fifo->head + firstSize) % fifo->size;
171
172 size_t remaining = count - firstSize;
173 if (remaining > 0)
174 {
175 memcpy(fifo->buffer + fifo->head, (uint8_t*)buffer + firstSize, remaining);
176 fifo->head = (fifo->head + remaining) % fifo->size;
177 }
178
179 return count;
180}
181
182/**
183 * @brief Advance the head of the fifo buffer.
184 *
185 * @param fifo Pointer to the fifo buffer structure.
186 * @param count The number of bytes to advance the head by.
187 */
188static inline void fifo_advance_head(fifo_t* fifo, size_t count)
189{
190 fifo->head = (fifo->head + count) % fifo->size;
191}
192
193/**
194 * @brief Advance the tail of the fifo buffer.
195 *
196 * @param fifo Pointer to the fifo buffer structure.
197 * @param count The number of bytes to advance the tail by.
198 */
199static inline void fifo_advance_tail(fifo_t* fifo, size_t count)
200{
201 fifo->tail = (fifo->tail + count) % fifo->size;
202}
203
204/** @} */
EFI_PHYSICAL_ADDRESS buffer
Definition main.c:237
static size_t fifo_read(fifo_t *fifo, void *buffer, size_t count)
Read data from a fifo buffer at a specific offset.
Definition fifo.h:113
static size_t fifo_bytes_writeable(const fifo_t *fifo)
Return the number of bytes available for writing in a fifo buffer.
Definition fifo.h:95
static void fifo_advance_tail(fifo_t *fifo, size_t count)
Advance the tail of the fifo buffer.
Definition fifo.h:199
static void fifo_reset(fifo_t *fifo)
Reset a fifo buffer.
Definition fifo.h:67
static void fifo_init(fifo_t *fifo, uint8_t *buffer, size_t size)
Initialize a fifo buffer.
Definition fifo.h:54
static size_t fifo_write(fifo_t *fifo, const void *buffer, size_t count)
Write data to the fifo buffer.
Definition fifo.h:155
static size_t fifo_bytes_readable(const fifo_t *fifo)
Return the number of bytes available for reading in a fifo buffer.
Definition fifo.h:79
static void fifo_advance_head(fifo_t *fifo, size_t count)
Advance the head of the fifo buffer.
Definition fifo.h:188
static atomic_long count
Definition main.c:11
__UINT8_TYPE__ uint8_t
Definition stdint.h:11
_PUBLIC void * memcpy(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
Definition memcpy.c:61
FIFO Buffer.
Definition fifo.h:20
size_t size
The total size of the buffer.
Definition fifo.h:22
size_t head
The position to write to.
Definition fifo.h:23
uint8_t * buffer
Pointer to the buffer memory.
Definition fifo.h:21
size_t tail
The position to start reading from.
Definition fifo.h:24