ChibiOS/RT  5.1.0
chfifo.h
Go to the documentation of this file.
1 /*
2  ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio.
3 
4  This file is part of ChibiOS.
5 
6  ChibiOS is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 3 of the License, or
9  (at your option) any later version.
10 
11  ChibiOS is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 /**
21  * @file chfifo.h
22  * @brief Objects FIFO structures and macros.
23  * @details This module implements a generic FIFO queue of objects by
24  * coupling a Guarded Memory Pool (for objects storage) and
25  * a MailBox.<br>
26  * On the sender side free objects are taken from the pool, filled
27  * and then sent to the receiver, on the receiver side objects are
28  * fetched, used and then returned to the pool.
29  * Operations defined for object FIFOs:
30  * - <b>Take</b>: An object is taken from the pool of the free
31  * objects, can be blocking.
32  * - <b>Return</b>: An object is returned to the pool of the
33  * free objects, it is guaranteed to be non-blocking.
34  * - <b>Send</b>: An object is sent through the mailbox, it is
35  * guaranteed to be non-blocking
36  * - <b>Receive</b>: An object is received from the mailbox,
37  * can be blocking.
38  * .
39  *
40  * @addtogroup objects_fifo
41  * @{
42  */
43 
44 #ifndef CHFIFO_H
45 #define CHFIFO_H
46 
47 #if !defined(CH_CFG_USE_OBJ_FIFOS)
48 #define CH_CFG_USE_OBJ_FIFOS TRUE
49 #endif
50 
51 #if (CH_CFG_USE_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__)
52 
53 /*===========================================================================*/
54 /* Module constants. */
55 /*===========================================================================*/
56 
57 /*===========================================================================*/
58 /* Module pre-compile time settings. */
59 /*===========================================================================*/
60 
61 /*===========================================================================*/
62 /* Derived constants and error checks. */
63 /*===========================================================================*/
64 
65 #if CH_CFG_USE_MEMPOOLS == FALSE
66 #error "CH_CFG_USE_OBJ_FIFOS requires CH_CFG_USE_MEMPOOLS"
67 #endif
68 
69 #if CH_CFG_USE_SEMAPHORES == FALSE
70 #error "CH_CFG_USE_OBJ_FIFOS requires CH_CFG_USE_SEMAPHORES"
71 #endif
72 
73 #if CH_CFG_USE_MAILBOXES == FALSE
74 #error "CH_CFG_USE_OBJ_FIFOS requires CH_CFG_USE_MAILBOXES"
75 #endif
76 
77 /*===========================================================================*/
78 /* Module data structures and types. */
79 /*===========================================================================*/
80 
81 /**
82  * @brief Type of an objects FIFO.
83  */
84 typedef struct ch_objects_fifo {
85  /**
86  * @brief Pool of the free objects.
87  */
89  /**
90  * @brief Mailbox of the sent objects.
91  */
94 
95 /*===========================================================================*/
96 /* Module macros. */
97 /*===========================================================================*/
98 
99 /*===========================================================================*/
100 /* External declarations. */
101 /*===========================================================================*/
102 
103 #ifdef __cplusplus
104 extern "C" {
105 #endif
106 
107 #ifdef __cplusplus
108 }
109 #endif
110 
111 /*===========================================================================*/
112 /* Module inline functions. */
113 /*===========================================================================*/
114 
115 /**
116  * @brief Initializes a FIFO object.
117  * @pre The messages size must be a multiple of the alignment
118  * requirement.
119  *
120  * @param[out] ofp pointer to a @p objects_fifo_t structure
121  * @param[in] objsize size of objects
122  * @param[in] objn number of objects available
123  * @param[in] objalign required objects alignment
124  * @param[in] objbuf pointer to the buffer of objects, it must be able
125  * to hold @p objn objects of @p objsize size with
126  * @p objealign alignment
127  * @param[in] msgbuf pointer to the buffer of messages, it must be able
128  * to hold @p objn messages
129  *
130  * @init
131  */
132 static inline void chFifoObjectInit(objects_fifo_t *ofp, size_t objsize,
133  size_t objn, unsigned objalign,
134  void *objbuf, msg_t *msgbuf) {
135 
136  chGuardedPoolObjectInitAligned(&ofp->free, objsize, objalign);
137  chGuardedPoolLoadArray(&ofp->free, objbuf, objn);
138  chMBObjectInit(&ofp->mbx, msgbuf, objn);
139 }
140 
141 /**
142  * @brief Allocates a free object.
143  *
144  * @param[in] ofp pointer to a @p objects_fifo_t structure
145  * @return The pointer to the allocated object.
146  * @retval NULL if an object is not immediately available.
147  *
148  * @iclass
149  */
150 static inline void *chFifoTakeObjectI(objects_fifo_t *ofp) {
151 
152  return chGuardedPoolAllocI(&ofp->free);
153 }
154 
155 /**
156  * @brief Allocates a free object.
157  *
158  * @param[in] ofp pointer to a @p objects_fifo_t structure
159  * @param[in] timeout the number of ticks before the operation timeouts,
160  * the following special values are allowed:
161  * - @a TIME_IMMEDIATE immediate timeout.
162  * - @a TIME_INFINITE no timeout.
163  * .
164  * @return The pointer to the allocated object.
165  * @retval NULL if an object is not available within the specified
166  * timeout.
167  *
168  * @sclass
169  */
170 static inline void *chFifoTakeObjectTimeoutS(objects_fifo_t *ofp,
171  sysinterval_t timeout) {
172 
173  return chGuardedPoolAllocTimeoutS(&ofp->free, timeout);
174 }
175 
176 /**
177  * @brief Allocates a free object.
178  *
179  * @param[in] ofp pointer to a @p objects_fifo_t structure
180  * @param[in] timeout the number of ticks before the operation timeouts,
181  * the following special values are allowed:
182  * - @a TIME_IMMEDIATE immediate timeout.
183  * - @a TIME_INFINITE no timeout.
184  * .
185  * @return The pointer to the allocated object.
186  * @retval NULL if an object is not available within the specified
187  * timeout.
188  *
189  * @api
190  */
191 static inline void *chFifoTakeObjectTimeout(objects_fifo_t *ofp,
192  sysinterval_t timeout) {
193 
194  return chGuardedPoolAllocTimeout(&ofp->free, timeout);
195 }
196 
197 /**
198  * @brief Releases a fetched object.
199  *
200  * @param[in] ofp pointer to a @p objects_fifo_t structure
201  * @param[in] objp pointer to the object to be released
202  *
203  * @iclass
204  */
205 static inline void chFifoReturnObjectI(objects_fifo_t *ofp,
206  void *objp) {
207 
208  chGuardedPoolFreeI(&ofp->free, objp);
209 }
210 
211 /**
212  * @brief Releases a fetched object.
213  *
214  * @param[in] ofp pointer to a @p objects_fifo_t structure
215  * @param[in] objp pointer to the object to be released
216  *
217  * @sclass
218  */
219 static inline void chFifoReturnObjectS(objects_fifo_t *ofp,
220  void *objp) {
221 
222  chGuardedPoolFreeS(&ofp->free, objp);
223 }
224 
225 /**
226  * @brief Releases a fetched object.
227  *
228  * @param[in] ofp pointer to a @p objects_fifo_t structure
229  * @param[in] objp pointer to the object to be released
230  *
231  * @api
232  */
233 static inline void chFifoReturnObject(objects_fifo_t *ofp,
234  void *objp) {
235 
236  chGuardedPoolFree(&ofp->free, objp);
237 }
238 
239 /**
240  * @brief Posts an object.
241  * @note By design the object can be always immediately posted.
242  *
243  * @param[in] ofp pointer to a @p objects_fifo_t structure
244  * @param[in] objp pointer to the object to be posted
245  *
246  * @iclass
247  */
248 static inline void chFifoSendObjectI(objects_fifo_t *ofp,
249  void *objp) {
250  msg_t msg;
251 
252  msg = chMBPostI(&ofp->mbx, (msg_t)objp);
253  chDbgAssert(msg == MSG_OK, "post failed");
254 }
255 
256 /**
257  * @brief Posts an object.
258  * @note By design the object can be always immediately posted.
259  *
260  * @param[in] ofp pointer to a @p objects_fifo_t structure
261  * @param[in] objp pointer to the object to be posted
262  *
263  * @sclass
264  */
265 static inline void chFifoSendObjectS(objects_fifo_t *ofp,
266  void *objp) {
267  msg_t msg;
268 
269  msg = chMBPostTimeoutS(&ofp->mbx, (msg_t)objp, TIME_IMMEDIATE);
270  chDbgAssert(msg == MSG_OK, "post failed");
271 }
272 
273 /**
274  * @brief Posts an object.
275  * @note By design the object can be always immediately posted.
276  *
277  * @param[in] ofp pointer to a @p objects_fifo_t structure
278  * @param[in] objp pointer to the object to be released
279  *
280  * @api
281  */
282 static inline void chFifoSendObject(objects_fifo_t *ofp, void *objp) {
283 
284  msg_t msg;
285 
286  msg = chMBPostTimeout(&ofp->mbx, (msg_t)objp, TIME_IMMEDIATE);
287  chDbgAssert(msg == MSG_OK, "post failed");
288 }
289 
290 /**
291  * @brief Posts an high priority object.
292  * @note By design the object can be always immediately posted.
293  *
294  * @param[in] ofp pointer to a @p objects_fifo_t structure
295  * @param[in] objp pointer to the object to be posted
296  *
297  * @iclass
298  */
299 static inline void chFifoSendObjectAheadI(objects_fifo_t *ofp,
300  void *objp) {
301  msg_t msg;
302 
303  msg = chMBPostAheadI(&ofp->mbx, (msg_t)objp);
304  chDbgAssert(msg == MSG_OK, "post failed");
305 }
306 
307 /**
308  * @brief Posts an high priority object.
309  * @note By design the object can be always immediately posted.
310  *
311  * @param[in] ofp pointer to a @p objects_fifo_t structure
312  * @param[in] objp pointer to the object to be posted
313  *
314  * @sclass
315  */
316 static inline void chFifoSendObjectAheadS(objects_fifo_t *ofp,
317  void *objp) {
318  msg_t msg;
319 
320  msg = chMBPostAheadTimeoutS(&ofp->mbx, (msg_t)objp, TIME_IMMEDIATE);
321  chDbgAssert(msg == MSG_OK, "post failed");
322 }
323 
324 /**
325  * @brief Posts an high priority object.
326  * @note By design the object can be always immediately posted.
327  *
328  * @param[in] ofp pointer to a @p objects_fifo_t structure
329  * @param[in] objp pointer to the object to be released
330  *
331  * @api
332  */
333 static inline void chFifoSendObjectAhead(objects_fifo_t *ofp, void *objp) {
334 
335  msg_t msg;
336 
337  msg = chMBPostAheadTimeout(&ofp->mbx, (msg_t)objp, TIME_IMMEDIATE);
338  chDbgAssert(msg == MSG_OK, "post failed");
339 }
340 
341 /**
342  * @brief Fetches an object.
343  *
344  * @param[in] ofp pointer to a @p objects_fifo_t structure
345  * @param[in] objpp pointer to the fetched object reference
346  * @return The operation status.
347  * @retval MSG_OK if an object has been correctly fetched.
348  * @retval MSG_TIMEOUT if the FIFO is empty and a message cannot be fetched.
349  *
350  * @iclass
351  */
352 static inline msg_t chFifoReceiveObjectI(objects_fifo_t *ofp,
353  void **objpp) {
354 
355  return chMBFetchI(&ofp->mbx, (msg_t *)objpp);
356 }
357 
358 /**
359  * @brief Fetches an object.
360  *
361  * @param[in] ofp pointer to a @p objects_fifo_t structure
362  * @param[in] objpp pointer to the fetched object reference
363  * @param[in] timeout the number of ticks before the operation timeouts,
364  * the following special values are allowed:
365  * - @a TIME_IMMEDIATE immediate timeout.
366  * - @a TIME_INFINITE no timeout.
367  * .
368  * @return The operation status.
369  * @retval MSG_OK if an object has been correctly fetched.
370  * @retval MSG_TIMEOUT if the operation has timed out.
371  *
372  * @sclass
373  */
375  void **objpp,
376  sysinterval_t timeout) {
377 
378  return chMBFetchTimeoutS(&ofp->mbx, (msg_t *)objpp, timeout);
379 }
380 
381 /**
382  * @brief Fetches an object.
383  *
384  * @param[in] ofp pointer to a @p objects_fifo_t structure
385  * @param[in] objpp pointer to the fetched object reference
386  * @param[in] timeout the number of ticks before the operation timeouts,
387  * the following special values are allowed:
388  * - @a TIME_IMMEDIATE immediate timeout.
389  * - @a TIME_INFINITE no timeout.
390  * .
391  * @return The operation status.
392  * @retval MSG_OK if an object has been correctly fetched.
393  * @retval MSG_TIMEOUT if the operation has timed out.
394  *
395  * @api
396  */
398  void **objpp,
399  sysinterval_t timeout) {
400 
401  return chMBFetchTimeout(&ofp->mbx, (msg_t *)objpp, timeout);
402 }
403 #endif /* CH_CFG_USE_OBJ_FIFOS == TRUE */
404 
405 #endif /* CHFIFO_H */
406 
407 /** @} */
static void chFifoSendObject(objects_fifo_t *ofp, void *objp)
Posts an object.
Definition: chfifo.h:282
mailbox_t mbx
Mailbox of the sent objects.
Definition: chfifo.h:92
msg_t chMBFetchTimeoutS(mailbox_t *mbp, msg_t *msgp, sysinterval_t timeout)
Retrieves a message from a mailbox.
Definition: chmboxes.c:444
static void chFifoSendObjectAhead(objects_fifo_t *ofp, void *objp)
Posts an high priority object.
Definition: chfifo.h:333
msg_t chMBPostTimeoutS(mailbox_t *mbp, msg_t msg, sysinterval_t timeout)
Posts a message into a mailbox.
Definition: chmboxes.c:194
uint64_t sysinterval_t
Type of time interval.
Definition: chtime.h:150
static void chFifoObjectInit(objects_fifo_t *ofp, size_t objsize, size_t objn, unsigned objalign, void *objbuf, msg_t *msgbuf)
Initializes a FIFO object.
Definition: chfifo.h:132
void * chGuardedPoolAllocTimeout(guarded_memory_pool_t *gmp, sysinterval_t timeout)
Allocates an object from a guarded memory pool.
Definition: chmempools.c:297
static void chFifoSendObjectAheadS(objects_fifo_t *ofp, void *objp)
Posts an high priority object.
Definition: chfifo.h:316
static void * chFifoTakeObjectTimeout(objects_fifo_t *ofp, sysinterval_t timeout)
Allocates a free object.
Definition: chfifo.h:191
static void chFifoSendObjectI(objects_fifo_t *ofp, void *objp)
Posts an object.
Definition: chfifo.h:248
msg_t chMBPostAheadI(mailbox_t *mbp, msg_t msg)
Posts an high priority message into a mailbox.
Definition: chmboxes.c:368
msg_t chMBFetchI(mailbox_t *mbp, msg_t *msgp)
Retrieves a message from a mailbox.
Definition: chmboxes.c:493
static void * chGuardedPoolAllocI(guarded_memory_pool_t *gmp)
Allocates an object from a guarded memory pool.
Definition: chmempools.h:265
void chGuardedPoolLoadArray(guarded_memory_pool_t *gmp, void *p, size_t n)
Loads a guarded memory pool with an array of static objects.
Definition: chmempools.c:242
static void chFifoReturnObjectS(objects_fifo_t *ofp, void *objp)
Releases a fetched object.
Definition: chfifo.h:219
static void chGuardedPoolFreeI(guarded_memory_pool_t *gmp, void *objp)
Releases an object into a guarded memory pool.
Definition: chmempools.h:289
Type of an objects FIFO.
Definition: chfifo.h:84
static void chFifoSendObjectAheadI(objects_fifo_t *ofp, void *objp)
Posts an high priority object.
Definition: chfifo.h:299
static void chFifoReturnObjectI(objects_fifo_t *ofp, void *objp)
Releases a fetched object.
Definition: chfifo.h:205
static msg_t chFifoReceiveObjectTimeout(objects_fifo_t *ofp, void **objpp, sysinterval_t timeout)
Fetches an object.
Definition: chfifo.h:397
#define MSG_OK
Normal wakeup message.
Definition: chschd.h:39
#define chDbgAssert(c, r)
Condition assertion.
Definition: chdebug.h:127
static msg_t chFifoReceiveObjectTimeoutS(objects_fifo_t *ofp, void **objpp, sysinterval_t timeout)
Fetches an object.
Definition: chfifo.h:374
static void * chFifoTakeObjectI(objects_fifo_t *ofp)
Allocates a free object.
Definition: chfifo.h:150
void chGuardedPoolObjectInitAligned(guarded_memory_pool_t *gmp, size_t size, unsigned align)
Initializes an empty guarded memory pool.
Definition: chmempools.c:221
msg_t chMBPostAheadTimeoutS(mailbox_t *mbp, msg_t msg, sysinterval_t timeout)
Posts an high priority message into a mailbox.
Definition: chmboxes.c:319
void * chGuardedPoolAllocTimeoutS(guarded_memory_pool_t *gmp, sysinterval_t timeout)
Allocates an object from a guarded memory pool.
Definition: chmempools.c:270
void chGuardedPoolFree(guarded_memory_pool_t *gmp, void *objp)
Releases an object into a guarded memory pool.
Definition: chmempools.c:320
msg_t chMBFetchTimeout(mailbox_t *mbp, msg_t *msgp, sysinterval_t timeout)
Retrieves a message from a mailbox.
Definition: chmboxes.c:415
#define TIME_IMMEDIATE
Zero interval specification for some functions with a timeout specification.
Definition: chtime.h:45
static void chFifoReturnObject(objects_fifo_t *ofp, void *objp)
Releases a fetched object.
Definition: chfifo.h:233
guarded_memory_pool_t free
Pool of the free objects.
Definition: chfifo.h:88
msg_t chMBPostI(mailbox_t *mbp, msg_t msg)
Posts a message into a mailbox.
Definition: chmboxes.c:243
msg_t chMBPostTimeout(mailbox_t *mbp, msg_t msg, sysinterval_t timeout)
Posts a message into a mailbox.
Definition: chmboxes.c:165
Guarded memory pool descriptor.
Definition: chmempools.h:81
struct ch_objects_fifo objects_fifo_t
Type of an objects FIFO.
static msg_t chFifoReceiveObjectI(objects_fifo_t *ofp, void **objpp)
Fetches an object.
Definition: chfifo.h:352
msg_t chMBPostAheadTimeout(mailbox_t *mbp, msg_t msg, sysinterval_t timeout)
Posts an high priority message into a mailbox.
Definition: chmboxes.c:290
Structure representing a mailbox object.
Definition: chmboxes.h:56
static void * chFifoTakeObjectTimeoutS(objects_fifo_t *ofp, sysinterval_t timeout)
Allocates a free object.
Definition: chfifo.h:170
static void chGuardedPoolFreeS(guarded_memory_pool_t *gmp, void *objp)
Releases an object into a guarded memory pool.
Definition: chmempools.h:307
void chMBObjectInit(mailbox_t *mbp, msg_t *buf, size_t n)
Initializes a mailbox_t object.
Definition: chmboxes.c:87
static void chFifoSendObjectS(objects_fifo_t *ofp, void *objp)
Posts an object.
Definition: chfifo.h:265