version 2.8
gqueue.h
Go to the documentation of this file.
1 /*
2  * This file is subject to the terms of the GFX License. If a copy of
3  * the license was not distributed with this file, you can obtain one at:
4  *
5  * http://ugfx.org/license.html
6  */
7 
8 /**
9  * @file src/gqueue/gqueue.h
10  * @brief GQUEUE header file.
11  *
12  * @addtogroup GQUEUE
13  *
14  * @brief Module which provides queue management (only internally used)
15  *
16  * @details There are 3 types of queues:
17  * <ul><li><b>Asynchronous Queues (ASync) </b> - Queue operations never block</li>
18  * <li><b>Get Synchronous Queues (GSync) </b> - Queue Get operations block until something is placed in the Queue</li>
19  * <li><b>Put Synchronous Queues (PSync)</b> - Queue Put operations block until the element is removed from the Queue</li>
20  * <li><b>Fully Synchronous Queues (FSync)</b> - Queue GET and Put operations block</li>
21  * </ul>
22  * We need 4 types of queues even though fully synchronous queues support all operations including asynchronous
23  * operations because fully synchronous queues have the highest storage requirements. The other queue types are
24  * optimizations. Efficiency IS important to use (particularly RAM efficiency).
25  * In practice we only implement ASync, GSync and FSync queues as PSync queues are of dubious value.
26  * <br>
27  * We also define GDataBuffer which is a data buffer that supports being queued.
28  * @{
29  */
30 
31 #ifndef _GQUEUE_H
32 #define _GQUEUE_H
33 
34 #if GFX_USE_GQUEUE || defined(__DOXYGEN__)
35 
36 /**
37  * @brief A queue item
38  * @{
39  */
40 typedef struct gfxQueueASyncItem {
41  struct gfxQueueASyncItem *next;
43 
44 typedef struct gfxQueueFSyncItem {
45  struct gfxQueueFSyncItem *next;
46  gfxSem sem;
47 } gfxQueueFSyncItem;
48 /** @} */
49 
50 /**
51  * @brief A queue
52  * @{
53  */
54 typedef struct gfxQueueASync {
55  gfxQueueASyncItem *head;
56  gfxQueueASyncItem *tail;
58 
59 typedef struct gfxQueueGSync {
60  gfxQueueGSyncItem *head;
61  gfxQueueGSyncItem *tail;
62  gfxSem sem;
63 } gfxQueueGSync;
64 
65 typedef struct gfxQueueFSync {
66  gfxQueueFSyncItem *head;
67  gfxQueueFSyncItem *tail;
68  gfxSem sem;
69 } gfxQueueFSync;
70 /** @} */
71 
72 /**
73  * @brief A Data Buffer Queue
74  * @note This structure is followed immediately by the data itself.
75  * When allocating the buffers for the data put this structure
76  * at the beginning of the buffer.
77  */
78 typedef struct GDataBuffer {
79  gfxQueueGSyncItem next; // @< Used for queueing the buffers
80  size_t size; // @< The size of the buffer area following this structure (in bytes)
81  size_t len; // @< The length of the data in the buffer area (in bytes)
82 } GDataBuffer;
83 
84 /*===========================================================================*/
85 /* Function declarations. */
86 /*===========================================================================*/
87 
88 #ifdef __cplusplus
89 extern "C" {
90 #endif
91 
92 /**
93  * @name Initialisation functions
94  * @brief Initialise a queue.
95  *
96  * @param[in] pqueue A pointer to the queue
97  *
98  * @note Whilst queues are normally FIFO, a GFX queue also supports push and pop operations.
99  * A pop operation is the same as normal get from the queue but a push places the item
100  * at the head of the queue instead of the tail (as a put would).
101  *
102  * @api
103  * @{
104  */
105 void gfxQueueASyncInit(gfxQueueASync *pqueue);
106 void gfxQueueGSyncInit(gfxQueueGSync *pqueue);
107 void gfxQueueFSyncInit(gfxQueueFSync *pqueue);
108 /** @} */
109 
110 /**
111  * @name Deinitialisation functions
112  * @brief De-Initialise a queue.
113  *
114  * @param[in] pqueue A pointer to the queue
115  *
116  * @api
117  * @{
118  */
119 #define gfxQueueASyncDeinit(pqueue)
120 void gfxQueueGSyncDeinit(gfxQueueGSync *pqueue);
121 void gfxQueueFSyncDeinit(gfxQueueFSync *pqueue);
122 /** @} */
123 
124 /**
125  * @name Get() Functions
126  * @brief Get an item from the head of the queue (and remove it from the queue).
127  * @return NULL if the timeout expires before an item is available
128  *
129  * @param[in] pqueue A pointer to the queue
130  * @param[in] ms The maxmimum time to wait for an item. For ASync queues this parameter is
131  * not specified as TIME_IMMEDIATE is assumed.
132  *
133  * @note The routines ending in "I" are interrupt/system/iclass level routines.
134  *
135  * @api
136  * @{
137  */
138 gfxQueueASyncItem *gfxQueueASyncGet(gfxQueueASync *pqueue);
139 gfxQueueASyncItem *gfxQueueASyncGetI(gfxQueueASync *pqueue);
140 gfxQueueGSyncItem *gfxQueueGSyncGet(gfxQueueGSync *pqueue, delaytime_t ms);
141 gfxQueueGSyncItem *gfxQueueGSyncGetI(gfxQueueGSync *pqueue);
142 gfxQueueFSyncItem *gfxQueueFSyncGet(gfxQueueFSync *pqueue, delaytime_t ms);
143 /** @} */
144 
145 /**
146  * @name Put() Functions
147  * @brief Put an item on the end of the queue.
148  * @return none for ASync and GSync queues; For FSync queues - FALSE on timeout, otherwise TRUE
149  *
150  * @param[in] pqueue A pointer to the queue
151  * @param[in] pitem A pointer to the queue item
152  * @param[in] ms The maxmimum time to wait for an item to be removed from the queue (only for FSync queues)
153  *
154  * @note FSync: Use a delay time of TIME_IMMEDIATE if you don't want to wait until the
155  * item is removed from the queue. Note that even if the timeout occurs - the item
156  * remains in the queue.
157  * @note The routines ending in "I" are interrupt/system/iclass level routines.
158  *
159  * @api
160  * @{
161  */
162 void gfxQueueASyncPut(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem);
163 void gfxQueueASyncPutI(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem);
164 void gfxQueueGSyncPut(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem);
165 void gfxQueueGSyncPutI(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem);
166 bool_t gfxQueueFSyncPut(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem, delaytime_t ms);
167 /** @} */
168 
169 /**
170  * @name Pop() Functions
171  * @brief Pop an item from the head of the queue (and remove it from the queue).
172  * @details This is exactly the same as the Get operation above.
173  *
174  * @api
175  * @{
176  */
177 #define gfxQueueASyncPop(pqueue) gfxQueueASyncGet(pqueue)
178 #define gfxQueueASyncPopI(pqueue) gfxQueueASyncGetI(pqueue)
179 #define gfxQueueGSyncPop(pqueue, ms) gfxQueueGSyncGet(pqueue, ms)
180 #define gfxQueueFSyncPop(pqueue, ms) gfxQueueFSyncGet(pqueue, ms)
181 /** @} */
182 
183 /**
184  * @name Push() Functions
185  * @brief Push an item into the start of the queue.
186  * @return none for ASync and GSync queues; For FSync queues - FALSE on timeout, otherwise TRUE
187  *
188  * @param[in] pqueue A pointer to the queue
189  * @param[in] pitem A pointer to the queue item
190  * @param[in] ms The maxmimum time to wait for an item to be popped (only for FSync queues)
191  *
192  * @note FSync: Use a delay time of TIME_IMMEDIATE if you don't want to wait until the
193  * item is removed from the queue. Note that even if the timeout occurs - the item
194  * remains in the queue.
195  * @note The routines ending in "I" are interrupt/system/iclass level routines.
196  *
197  * @api
198  * @{
199  */
200 void gfxQueueASyncPush(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem);
201 void gfxQueueASyncPushI(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem);
202 void gfxQueueGSyncPush(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem);
203 void gfxQueueGSyncPushI(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem);
204 bool_t gfxQueueFSyncPush(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem, delaytime_t ms);
205 /** @} */
206 
207 /**
208  * @name Insert() Functions
209  * @brief Insert an item on the queue after the specified item.
210  * @return none for ASync and GSync queues; For FSync queues - FALSE on timeout, otherwise TRUE
211  *
212  * @param[in] pqueue A pointer to the queue
213  * @param[in] pitem A pointer to the queue item
214  * @param[in] pafter A pointer to the queue item this new item must be inserted after. If NULL or
215  * pafter can't be found in the queue, it puts the new item at the end of the queue.
216  * @param[in] ms The maxmimum time to wait for an item to be removed from the queue (only for FSync queues)
217  *
218  * @note FSync: Use a delay time of TIME_IMMEDIATE if you don't want to wait until the
219  * item is removed from the queue. Note that even if the timeout occurs - the item
220  * remains in the queue.
221  * @note The routines ending in "I" are interrupt/system/iclass level routines.
222  *
223  * @api
224  * @{
225  */
226 void gfxQueueASyncInsert(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem, gfxQueueASyncItem *pafter);
227 void gfxQueueASyncInsertI(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem, gfxQueueASyncItem *pafter);
228 void gfxQueueGSyncInsert(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem, gfxQueueASyncItem *pafter);
229 void gfxQueueGSyncInsertI(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem, gfxQueueASyncItem *pafter);
230 bool_t gfxQueueFSyncInsert(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem, gfxQueueASyncItem *pafter, delaytime_t ms);
231 /** @} */
232 
233 /**
234  * @name Remove() Functions
235  * @brief Remove an item from the queue.
236  * @note Removes the specified item from the queue where-ever it is in the queue
237  *
238  * @param[in] pqueue A pointer to the queue
239  * @param[in] pitem A pointer to the queue item
240  *
241  * @note If the item isn't in the queue the routine just returns.
242  * @note If a process is waiting on the Put/Push operation for the item, that process
243  * will be signaled.
244  * @note The routines ending in "I" are interrupt/system/iclass level routines.
245  *
246  * @api
247  * @{
248  */
249 void gfxQueueASyncRemove(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem);
250 void gfxQueueASyncRemoveI(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem);
251 void gfxQueueGSyncRemove(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem);
252 void gfxQueueGSyncRemoveI(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem);
253 void gfxQueueFSyncRemove(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem);
254 /** @} */
255 
256 /**
257  * @name isEmpty() Functions
258  * @brief Is the queue empty?
259  * @return TRUE if the queue is empty
260  *
261  * @param[in] pqueue A pointer to the queue
262  *
263  * @note The routines ending in "I" are interrupt/system/iclass level routines.
264  *
265  * @api
266  * @{
267  */
268 #define gfxQueueASyncIsEmpty(pqueue) ((pqueue)->head == 0)
269 #define gfxQueueASyncIsEmptyI(pqueue) ((pqueue)->head == 0)
270 #define gfxQueueGSyncIsEmpty(pqueue) ((pqueue)->head == 0)
271 #define gfxQueueGSyncIsEmptyI(pqueue) ((pqueue)->head == 0)
272 #define gfxQueueFSyncIsEmpty(pqueue) ((pqueue)->head == 0)
273 #define gfxQueueFSyncIsEmptyI(pqueue) ((pqueue)->head == 0)
274 /** @} */
275 
276 /**
277  * @name IsInQueue() Functions
278  * @brief Is an item in the queue?
279  * @return TRUE if the item is in the queue?
280  *
281  * @param[in] pqueue A pointer to the queue
282  * @param[in] pitem A pointer to the queue item
283  *
284  * @note This operation may be expensive.
285  * @note The routines ending in "I" are interrupt/system/iclass level routines.
286  *
287  * @api
288  * @{
289  */
290 bool_t gfxQueueASyncIsIn(gfxQueueASync *pqueue, const gfxQueueASyncItem *pitem);
291 bool_t gfxQueueASyncIsInI(gfxQueueASync *pqueue, const gfxQueueASyncItem *pitem);
292 bool_t gfxQueueGSyncIsIn(gfxQueueGSync *pqueue, const gfxQueueGSyncItem *pitem);
293 bool_t gfxQueueGSyncIsInI(gfxQueueGSync *pqueue, const gfxQueueGSyncItem *pitem);
294 bool_t gfxQueueFSyncIsIn(gfxQueueFSync *pqueue, const gfxQueueFSyncItem *pitem);
295 bool_t gfxQueueFSyncIsInI(gfxQueueFSync *pqueue, const gfxQueueFSyncItem *pitem);
296 /** @} */
297 
298 /**
299  * @name Peek() Functions
300  * @brief Get the first item from the head of the queue but do not remove it from the queue.
301  * @return NULL if no item is available.
302  *
303  * @param[in] pqueue A pointer to the queue
304  *
305  * @note This call does not block.
306  * @note This can be used as the first call to iterate all the elements in the queue.
307  * @note As that item is still on the queue, it should be treated as read-only. It could
308  * also be removed from the queue at any time by another thread (thereby altering the
309  * queue item).
310  * @note The routines ending in "I" are interrupt/system/iclass level routines.
311  *
312  * @api
313  * @{
314  */
315 #define gfxQueueASyncPeek(pqueue) ((const gfxQueueASyncItem *)((pqueue)->head))
316 #define gfxQueueASyncPeekI(pqueue) ((const gfxQueueASyncItem *)((pqueue)->head))
317 #define gfxQueueGSyncPeek(pqueue) ((const gfxQueueGSyncItem *)((pqueue)->head))
318 #define gfxQueueGSyncPeekI(pqueue) ((const gfxQueueGSyncItem *)((pqueue)->head))
319 #define gfxQueueFSyncPeek(pqueue) ((const gfxQueueFSyncItem *)((pqueue)->head))
320 #define gfxQueueFSyncPeekI(pqueue) ((const gfxQueueFSyncItem *)((pqueue)->head))
321 /** @} */
322 
323 /**
324  * @name Next() Functions
325  * @brief Get the next item in the queue (but do not remove it from the queue).
326  * @return NULL if no item is available.
327  *
328  * @param[in] pitem The previous item in the queue
329  *
330  * @note This call does not block.
331  * @note This can be used as subsequent calls to iterate all the elements in the queue.
332  * @note As that item is still on the queue, it should be treated as read-only. It could
333  * also be removed from the queue at any time by another thread (thereby altering the
334  * queue item).
335  * @note The routines ending in "I" are interrupt/system/iclass level routines.
336  *
337  * @api
338  * @{
339  */
340 #define gfxQueueASyncNext(pitem) ((const gfxQueueASyncItem *)((pitem)->next))
341 #define gfxQueueASyncNextI(pitem) ((const gfxQueueASyncItem *)((pitem)->next))
342 #define gfxQueueGSyncNext(pitem) ((const gfxQueueGSyncItem *)((pitem)->next))
343 #define gfxQueueGSyncNextI(pitem) ((const gfxQueueGSyncItem *)((pitem)->next))
344 #define gfxQueueFSyncNext(pitem) ((const gfxQueueFSyncItem *)((pitem)->next))
345 #define gfxQueueFSyncNextI(pitem) ((const gfxQueueFSyncItem *)((pitem)->next))
346 /** @} */
347 
348 /**
349  * @name BufferAlloc() Functions
350  * @brief Allocate some buffers and put them on the free list
351  * @return TRUE is it succeeded. FALSE on allocation failure.
352  *
353  * @param[in] num The number of buffers to allocate
354  * @param[in] size The size (in bytes) of each buffer
355  *
356  * @api
357  * @{
358  */
359 bool_t gfxBufferAlloc(unsigned num, size_t size);
360 /** @} */
361 
362 /**
363  * @name BufferIsAvailable() Functions
364  * @brief Is there one or more buffers currently available on the free list
365  * @return TRUE if there are buffers in the free list
366  *
367  * @api
368  * @{
369  */
370 bool_t gfxBufferIsAvailable(void);
371 /** @} */
372 
373 /**
374  * @name BufferGet() Functions
375  * @brief Get a buffer from the free list
376  * @return A GDataBuffer pointer or NULL if the timeout is exceeded
377  *
378  * @param[in] ms The maximum amount of time in milliseconds to wait for a buffer if one is not available.
379  *
380  * @api
381  * @{
382  */
383 GDataBuffer *gfxBufferGet(delaytime_t ms);
384 GDataBuffer *gfxBufferGetI(void);
385 /** @} */
386 
387 /**
388  * @name BufferRelease() Functions
389  * @brief Release a buffer back to the free list
390  *
391  * @param[in] pd The buffer to put (back) on the free-list.
392  *
393  * @note This call should be used to return any buffers that were taken from
394  * the free-list once they have been finished with. It can also be used
395  * to put new buffers onto the free-list. Just make sure the "size" field
396  * of the GDataBuffer structure has been filled in first.
397  *
398  * @api
399  * @{
400  */
401 void gfxBufferRelease(GDataBuffer *pd);
402 void gfxBufferReleaseI(GDataBuffer *pd);
403 /** @} */
404 
405 
406 #ifdef __cplusplus
407 }
408 #endif
409 
410 #endif /* GFX_USE_GQUEUE */
411 #endif /* _GQUEUE_H */
412 /** @} */
A Data Buffer Queue.
Definition: gqueue.h:78
A queue item.
Definition: gqueue.h:40
struct gfxQueueASyncItem gfxQueueASyncItem
A queue item.
A queue.
Definition: gqueue.h:54
A semaphore.
Definition: gos.h:105
struct gfxQueueASync gfxQueueASync
A queue.
struct GDataBuffer GDataBuffer
A Data Buffer Queue.