1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef FWK_RING_H
9 #define FWK_RING_H
10 
11 #include <stdbool.h>
12 #include <stddef.h>
13 
14 /*!
15  * \addtogroup GroupLibFramework Framework
16  * \{
17  */
18 
19 /*!
20  *
21  * \addtogroup GroupRing Ring Buffers
22  *
23  * \brief Ring buffer interface.
24  *
25  * \details A ring buffer is a buffer that behaves as though both ends are
26  *      connected. It acts like a continuous loop, overwriting old data, by
27  *      maintaining extra state.
28  *
29  * \{
30  */
31 
32 /*!
33  * \brief Ring buffer.
34  */
35 struct fwk_ring {
36     /*!
37      * \brief Internal storage.
38      *
39      * \details This is the storage within which reads and writes through the
40      *      ring buffer interface will take place.
41      */
42     char *storage;
43 
44     /*!
45      * \brief Size of ::fwk_ring::storage in bytes.
46      */
47     size_t capacity;
48 
49     /*!
50      * \brief Offset of the leading byte of buffered data.
51      */
52     size_t head;
53 
54     /*!
55      * \brief Offset of one byte past the trailing byte of buffered data.
56      */
57     size_t tail;
58 
59     /*!
60      * \brief Whether the buffer is at full capacity or not.
61      */
62     bool full;
63 };
64 
65 /*!
66  * \brief Initialize a ring buffer from existing storage.
67  *
68  * \param[out] ring Ring buffer to initialize.
69  * \param[in] storage Internal storage buffer.
70  * \param[in] storage_size Size of \p storage in bytes.
71  */
72 void fwk_ring_init(struct fwk_ring *ring, char *storage, size_t storage_size);
73 
74 /*!
75  * \brief Get the capacity of a ring buffer.
76  *
77  * \details The capacity represents the number of bytes a ring buffer can hold.
78  *
79  * \param[in] ring Ring buffer.
80  *
81  * \return Capacity of \p ring in bytes.
82  */
83 size_t fwk_ring_get_capacity(const struct fwk_ring *ring);
84 
85 /*!
86  * \brief Get the length of a ring buffer.
87  *
88  * \details The length represents the number of bytes a ring buffer is currently
89  *      holding.
90  *
91  * \param[in] ring Ring buffer.
92  *
93  * \return Length of \p ring in bytes.
94  */
95 size_t fwk_ring_get_length(const struct fwk_ring *ring);
96 
97 /*!
98  * \brief Get the number of bytes still available in a ring buffer.
99  *
100  * \param[in] ring Ring buffer.
101  *
102  * \return Number of remaining bytes in \p ring.
103  */
104 size_t fwk_ring_get_free(const struct fwk_ring *ring);
105 
106 /*!
107  * \brief Get whether a ring buffer is full or not.
108  *
109  * \param[in] ring Ring buffer.
110  *
111  * \retval true The ring buffer is full.
112  * \retval false The ring buffer is not full.
113  */
114 bool fwk_ring_is_full(const struct fwk_ring *ring);
115 
116 /*!
117  * \brief Get whether a ring buffer is empty or not.
118  *
119  * \param[in] ring Ring buffer.
120  *
121  * \retval true The ring buffer is empty.
122  * \retval false The ring buffer is not empty.
123  */
124 bool fwk_ring_is_empty(const struct fwk_ring *ring);
125 
126 /*!
127  * \brief Pop data from the beginning of a ring buffer.
128  *
129  * \details Popping data from the ring buffer will drop it from the buffer.
130  *
131  * \note \p buffer may be \c NULL, in which case the data is simply discarded.
132  *
133  * \param[in, out] ring Ring buffer.
134  * \param[out] buffer Buffer to write the data to.
135  * \param[in] buffer_size Size of \p buffer in bytes.
136  *
137  * \return Number of bytes written to \p buffer.
138  */
139 size_t fwk_ring_pop(struct fwk_ring *ring, char *buffer, size_t buffer_size);
140 
141 /*!
142  * \brief Peek at data from the beginning of a ring buffer.
143  *
144  * \param[in, out] ring Ring buffer.
145  * \param[out] buffer Buffer to write the data to.
146  * \param[in] buffer_size Size of \p buffer in bytes.
147  *
148  * \return Number of bytes written to \p buffer.
149  */
150 size_t fwk_ring_peek(
151     const struct fwk_ring *ring,
152     char *buffer,
153     size_t buffer_size);
154 
155 /*!
156  * \brief Push data to the end of a ring buffer.
157  *
158  * \details Writing data past the capacity of the ring buffer will cause the
159  *      oldest data to be popped.
160  *
161  * \param[in, out] ring Ring buffer.
162  * \param[in] buffer Buffer to read data from.
163  * \param[in] buffer_size Size of \p buffer in bytes.
164  *
165  * \return Number of bytes written to \p ring.
166  */
167 size_t fwk_ring_push(
168     struct fwk_ring *ring,
169     const char *buffer,
170     size_t buffer_size);
171 
172 /*!
173  * \brief Clear all data from a ring buffer.
174  *
175  * \param[in, out] ring Ring buffer.
176  */
177 void fwk_ring_clear(struct fwk_ring *ring);
178 
179 /*!
180  * \}
181  */
182 
183 /*!
184  * \}
185  */
186 
187 #endif
188