1 /* ring_buffer.h: Simple ring buffer API */
2 
3 /*
4  * Copyright (c) 2015 Intel Corporation
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 /** @file */
9 
10 #ifndef ZEPHYR_INCLUDE_SYS_RING_BUFFER_H_
11 #define ZEPHYR_INCLUDE_SYS_RING_BUFFER_H_
12 
13 #include <kernel.h>
14 #include <sys/util.h>
15 #include <errno.h>
16 #include <string.h>
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21 
22 #define SIZE32_OF(x) (sizeof((x))/sizeof(uint32_t))
23 
24 /* The limit is used by algorithm for distinguishing between empty and full
25  * state.
26  */
27 #define RING_BUFFER_MAX_SIZE 0x80000000
28 
29 #define RING_BUFFER_SIZE_ASSERT_MSG \
30 	"Size too big, if it is the ring buffer test check custom max size"
31 /**
32  * @brief A structure to represent a ring buffer
33  */
34 struct ring_buf {
35 	uint32_t head;	 /**< Index in buf for the head element */
36 	uint32_t tail;	 /**< Index in buf for the tail element */
37 	union ring_buf_misc {
38 		struct ring_buf_misc_item_mode {
39 			uint32_t dropped_put_count; /**< Running tally of the
40 						     * number of failed put
41 						     * attempts.
42 						     */
43 		} item_mode;
44 		struct ring_buf_misc_byte_mode {
45 			uint32_t tmp_tail;
46 			uint32_t tmp_head;
47 		} byte_mode;
48 	} misc;
49 	uint32_t size;   /**< Size of buf in 32-bit chunks */
50 
51 	union ring_buf_buffer {
52 		uint32_t *buf32; /**< Memory region for stored entries */
53 		uint8_t *buf8;
54 	} buf;
55 	uint32_t mask;   /**< Modulo mask if size is a power of 2 */
56 
57 	struct k_spinlock lock;
58 };
59 
60 /**
61  * @defgroup ring_buffer_apis Ring Buffer APIs
62  * @ingroup datastructure_apis
63  * @{
64  */
65 
66 /**
67  * @brief Define and initialize a high performance ring buffer.
68  *
69  * This macro establishes a ring buffer whose size must be a power of 2;
70  * that is, the ring buffer contains 2^pow 32-bit words, where @a pow is
71  * the specified ring buffer size exponent. A high performance ring buffer
72  * doesn't require the use of modulo arithmetic operations to maintain itself.
73  *
74  * The ring buffer can be accessed outside the module where it is defined
75  * using:
76  *
77  * @code extern struct ring_buf <name>; @endcode
78  *
79  * @param name Name of the ring buffer.
80  * @param pow Ring buffer size exponent.
81  */
82 #define RING_BUF_ITEM_DECLARE_POW2(name, pow) \
83 	BUILD_ASSERT((1 << pow) < RING_BUFFER_MAX_SIZE,\
84 		RING_BUFFER_SIZE_ASSERT_MSG); \
85 	static uint32_t __noinit _ring_buffer_data_##name[BIT(pow)]; \
86 	struct ring_buf name = { \
87 		.size = (BIT(pow)),	  \
88 		.mask = (BIT(pow)) - 1, \
89 		.buf = { .buf32 = _ring_buffer_data_##name } \
90 	}
91 
92 /**
93  * @brief Define and initialize a standard ring buffer.
94  *
95  * This macro establishes a ring buffer of an arbitrary size. A standard
96  * ring buffer uses modulo arithmetic operations to maintain itself.
97  *
98  * The ring buffer can be accessed outside the module where it is defined
99  * using:
100  *
101  * @code extern struct ring_buf <name>; @endcode
102  *
103  * @param name Name of the ring buffer.
104  * @param size32 Size of ring buffer (in 32-bit words).
105  */
106 #define RING_BUF_ITEM_DECLARE_SIZE(name, size32) \
107 	BUILD_ASSERT(size32 < RING_BUFFER_MAX_SIZE,\
108 		RING_BUFFER_SIZE_ASSERT_MSG); \
109 	static uint32_t __noinit _ring_buffer_data_##name[size32]; \
110 	struct ring_buf name = { \
111 		.size = size32, \
112 		.buf = { .buf32 = _ring_buffer_data_##name} \
113 	}
114 
115 /**
116  * @brief Define and initialize a ring buffer for byte data.
117  *
118  * This macro establishes a ring buffer of an arbitrary size.
119  *
120  * The ring buffer can be accessed outside the module where it is defined
121  * using:
122  *
123  * @code extern struct ring_buf <name>; @endcode
124  *
125  * @param name  Name of the ring buffer.
126  * @param size8 Size of ring buffer (in bytes).
127  */
128 #define RING_BUF_DECLARE(name, size8) \
129 	BUILD_ASSERT(size8 < RING_BUFFER_MAX_SIZE,\
130 		RING_BUFFER_SIZE_ASSERT_MSG); \
131 	static uint8_t __noinit _ring_buffer_data_##name[size8]; \
132 	struct ring_buf name = { \
133 		.size = size8, \
134 		.buf = { .buf8 = _ring_buffer_data_##name} \
135 	}
136 
137 
138 /**
139  * @brief Initialize a ring buffer.
140  *
141  * This routine initializes a ring buffer, prior to its first use. It is only
142  * used for ring buffers not defined using RING_BUF_DECLARE,
143  * RING_BUF_ITEM_DECLARE_POW2 or RING_BUF_ITEM_DECLARE_SIZE.
144  *
145  * Setting @a size to a power of 2 establishes a high performance ring buffer
146  * that doesn't require the use of modulo arithmetic operations to maintain
147  * itself.
148  *
149  * @param buf Address of ring buffer.
150  * @param size Ring buffer size (in 32-bit words or bytes).
151  * @param data Ring buffer data area (uint32_t data[size] or uint8_t data[size]
152  *	       for bytes mode).
153  */
ring_buf_init(struct ring_buf * buf,uint32_t size,void * data)154 static inline void ring_buf_init(struct ring_buf *buf,
155 				 uint32_t size,
156 				 void *data)
157 {
158 	__ASSERT(size < RING_BUFFER_MAX_SIZE, RING_BUFFER_SIZE_ASSERT_MSG);
159 
160 	memset(buf, 0, sizeof(struct ring_buf));
161 	buf->size = size;
162 	buf->buf.buf32 = (uint32_t *)data;
163 	if (is_power_of_two(size)) {
164 		buf->mask = size - 1U;
165 	} else {
166 		buf->mask = 0U;
167 	}
168 }
169 
170 /**
171  * @brief Determine if a ring buffer is empty.
172  *
173  * @param buf Address of ring buffer.
174  *
175  * @return 1 if the ring buffer is empty, or 0 if not.
176  */
177 int ring_buf_is_empty(struct ring_buf *buf);
178 
179 /**
180  * @brief Reset ring buffer state.
181  *
182  * @param buf Address of ring buffer.
183  */
ring_buf_reset(struct ring_buf * buf)184 static inline void ring_buf_reset(struct ring_buf *buf)
185 {
186 	buf->head = 0;
187 	buf->tail = 0;
188 	memset(&buf->misc, 0, sizeof(buf->misc));
189 }
190 
191 /**
192  * @brief Determine free space in a ring buffer.
193  *
194  * @param buf Address of ring buffer.
195  *
196  * @return Ring buffer free space (in 32-bit words or bytes).
197  */
198 uint32_t ring_buf_space_get(struct ring_buf *buf);
199 
200 /**
201  * @brief Return ring buffer capacity.
202  *
203  * @param buf Address of ring buffer.
204  *
205  * @return Ring buffer capacity (in 32-bit words or bytes).
206  */
ring_buf_capacity_get(struct ring_buf * buf)207 static inline uint32_t ring_buf_capacity_get(struct ring_buf *buf)
208 {
209 	return buf->size;
210 }
211 
212 /**
213  * @brief Determine used space in a ring buffer.
214  *
215  * @param buf Address of ring buffer.
216  *
217  * @return Ring buffer space used (in 32-bit words or bytes).
218  */
219 uint32_t ring_buf_size_get(struct ring_buf *buf);
220 
221 /**
222  * @brief Write a data item to a ring buffer.
223  *
224  * This routine writes a data item to ring buffer @a buf. The data item
225  * is an array of 32-bit words (from zero to 1020 bytes in length),
226  * coupled with a 16-bit type identifier and an 8-bit integer value.
227  *
228  * @warning
229  * Use cases involving multiple writers to the ring buffer must prevent
230  * concurrent write operations, either by preventing all writers from
231  * being preempted or by using a mutex to govern writes to the ring buffer.
232  *
233  * @param buf Address of ring buffer.
234  * @param type Data item's type identifier (application specific).
235  * @param value Data item's integer value (application specific).
236  * @param data Address of data item.
237  * @param size32 Data item size (number of 32-bit words).
238  *
239  * @retval 0 Data item was written.
240  * @retval -EMSGSIZE Ring buffer has insufficient free space.
241  */
242 int ring_buf_item_put(struct ring_buf *buf, uint16_t type, uint8_t value,
243 		      uint32_t *data, uint8_t size32);
244 
245 /**
246  * @brief Read a data item from a ring buffer.
247  *
248  * This routine reads a data item from ring buffer @a buf. The data item
249  * is an array of 32-bit words (up to 1020 bytes in length),
250  * coupled with a 16-bit type identifier and an 8-bit integer value.
251  *
252  * @warning
253  * Use cases involving multiple reads of the ring buffer must prevent
254  * concurrent read operations, either by preventing all readers from
255  * being preempted or by using a mutex to govern reads to the ring buffer.
256  *
257  * @param buf Address of ring buffer.
258  * @param type Area to store the data item's type identifier.
259  * @param value Area to store the data item's integer value.
260  * @param data Area to store the data item. Can be NULL to discard data.
261  * @param size32 Size of the data item storage area (number of 32-bit chunks).
262  *
263  * @retval 0 Data item was fetched; @a size32 now contains the number of
264  *         32-bit words read into data area @a data.
265  * @retval -EAGAIN Ring buffer is empty.
266  * @retval -EMSGSIZE Data area @a data is too small; @a size32 now contains
267  *         the number of 32-bit words needed.
268  */
269 int ring_buf_item_get(struct ring_buf *buf, uint16_t *type, uint8_t *value,
270 		      uint32_t *data, uint8_t *size32);
271 
272 /**
273  * @brief Allocate buffer for writing data to a ring buffer.
274  *
275  * With this routine, memory copying can be reduced since internal ring buffer
276  * can be used directly by the user. Once data is written to allocated area
277  * number of bytes written can be confirmed (see @ref ring_buf_put_finish).
278  *
279  * @warning
280  * Use cases involving multiple writers to the ring buffer must prevent
281  * concurrent write operations, either by preventing all writers from
282  * being preempted or by using a mutex to govern writes to the ring buffer.
283  *
284  * @warning
285  * Ring buffer instance should not mix byte access and item access
286  * (calls prefixed with ring_buf_item_).
287  *
288  * @param[in]  buf  Address of ring buffer.
289  * @param[out] data Pointer to the address. It is set to a location within
290  *		    ring buffer.
291  * @param[in]  size Requested allocation size (in bytes).
292  *
293  * @return Size of allocated buffer which can be smaller than requested if
294  *	   there is not enough free space or buffer wraps.
295  */
296 uint32_t ring_buf_put_claim(struct ring_buf *buf,
297 			    uint8_t **data,
298 			    uint32_t size);
299 
300 /**
301  * @brief Indicate number of bytes written to allocated buffers.
302  *
303  * @warning
304  * Use cases involving multiple writers to the ring buffer must prevent
305  * concurrent write operations, either by preventing all writers from
306  * being preempted or by using a mutex to govern writes to the ring buffer.
307  *
308  * @warning
309  * Ring buffer instance should not mix byte access and item access
310  * (calls prefixed with ring_buf_item_).
311  *
312  * @param  buf  Address of ring buffer.
313  * @param  size Number of valid bytes in the allocated buffers.
314  *
315  * @retval 0 Successful operation.
316  * @retval -EINVAL Provided @a size exceeds free space in the ring buffer.
317  */
318 int ring_buf_put_finish(struct ring_buf *buf, uint32_t size);
319 
320 /**
321  * @brief Write (copy) data to a ring buffer.
322  *
323  * This routine writes data to a ring buffer @a buf.
324  *
325  * @warning
326  * Use cases involving multiple writers to the ring buffer must prevent
327  * concurrent write operations, either by preventing all writers from
328  * being preempted or by using a mutex to govern writes to the ring buffer.
329  *
330  * @warning
331  * Ring buffer instance should not mix byte access and item access
332  * (calls prefixed with ring_buf_item_).
333  *
334  * @param buf Address of ring buffer.
335  * @param data Address of data.
336  * @param size Data size (in bytes).
337  *
338  * @retval Number of bytes written.
339  */
340 uint32_t ring_buf_put(struct ring_buf *buf, const uint8_t *data, uint32_t size);
341 
342 /**
343  * @brief Get address of a valid data in a ring buffer.
344  *
345  * With this routine, memory copying can be reduced since internal ring buffer
346  * can be used directly by the user. Once data is processed it can be freed
347  * using @ref ring_buf_get_finish.
348  *
349  * @warning
350  * Use cases involving multiple reads of the ring buffer must prevent
351  * concurrent read operations, either by preventing all readers from
352  * being preempted or by using a mutex to govern reads to the ring buffer.
353  *
354  * @warning
355  * Ring buffer instance should not mix byte access and item access
356  * (calls prefixed with ring_buf_item_).
357  *
358  * @param[in]  buf  Address of ring buffer.
359  * @param[out] data Pointer to the address. It is set to a location within
360  *		    ring buffer.
361  * @param[in]  size Requested size (in bytes).
362  *
363  * @return Number of valid bytes in the provided buffer which can be smaller
364  *	   than requested if there is not enough free space or buffer wraps.
365  */
366 uint32_t ring_buf_get_claim(struct ring_buf *buf,
367 			    uint8_t **data,
368 			    uint32_t size);
369 
370 /**
371  * @brief Indicate number of bytes read from claimed buffer.
372  *
373  * @warning
374  * Use cases involving multiple reads of the ring buffer must prevent
375  * concurrent read operations, either by preventing all readers from
376  * being preempted or by using a mutex to govern reads to the ring buffer.
377  *
378  * @warning
379  * Ring buffer instance should not mix byte access and  item mode
380  * (calls prefixed with ring_buf_item_).
381  *
382  * @param  buf  Address of ring buffer.
383  * @param  size Number of bytes that can be freed.
384  *
385  * @retval 0 Successful operation.
386  * @retval -EINVAL Provided @a size exceeds valid bytes in the ring buffer.
387  */
388 int ring_buf_get_finish(struct ring_buf *buf, uint32_t size);
389 
390 /**
391  * @brief Read data from a ring buffer.
392  *
393  * This routine reads data from a ring buffer @a buf.
394  *
395  * @warning
396  * Use cases involving multiple reads of the ring buffer must prevent
397  * concurrent read operations, either by preventing all readers from
398  * being preempted or by using a mutex to govern reads to the ring buffer.
399  *
400  * @warning
401  * Ring buffer instance should not mix byte access and  item mode
402  * (calls prefixed with ring_buf_item_).
403  *
404  * @param buf  Address of ring buffer.
405  * @param data Address of the output buffer. Can be NULL to discard data.
406  * @param size Data size (in bytes).
407  *
408  * @retval Number of bytes written to the output buffer.
409  */
410 uint32_t ring_buf_get(struct ring_buf *buf, uint8_t *data, uint32_t size);
411 
412 /**
413  * @brief Peek at data from a ring buffer.
414  *
415  * This routine reads data from a ring buffer @a buf without removal.
416  *
417  * @warning
418  * Use cases involving multiple reads of the ring buffer must prevent
419  * concurrent read operations, either by preventing all readers from
420  * being preempted or by using a mutex to govern reads to the ring buffer.
421  *
422  * @warning
423  * Ring buffer instance should not mix byte access and  item mode
424  * (calls prefixed with ring_buf_item_).
425  *
426  * @warning
427  * Multiple calls to peek will result in the same data being 'peeked'
428  * multiple times. To remove data, use either @ref ring_buf_get or
429  * @ref ring_buf_get_claim followed by @ref ring_buf_get_finish with a
430  * non-zero `size`.
431  *
432  * @param buf  Address of ring buffer.
433  * @param data Address of the output buffer. Cannot be NULL.
434  * @param size Data size (in bytes).
435  *
436  * @retval Number of bytes written to the output buffer.
437  */
438 uint32_t ring_buf_peek(struct ring_buf *buf, uint8_t *data, uint32_t size);
439 
440 /**
441  * @}
442  */
443 
444 #ifdef __cplusplus
445 }
446 #endif
447 
448 #endif /* ZEPHYR_INCLUDE_SYS_RING_BUFFER_H_ */
449