1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
32 33 34 35
36 package ti.sysbios.knl;
37
38 import xdc.rov.ViewInfo;
39
40 /*!
41 * ======== Queue ========
42 * Queue manager.
43 *
44 * The Queue module makes available a set of functions that manipulate
45 * queue objects accessed through handles of type Queue_Handle.
46 * Each queue contains a linked sequence of zero or more elements
47 * referenced through variables of type Queue_Elem, which are
48 * embedded as the first field within a structure.
49 *
50 * In the Queue API descriptions, the APIs which disable interrupts before
51 * modifying the Queue are noted as "atomic", while APIs that do not disable
52 * interrupts are "non-atomic".
53 *
54 * Queues are represented as doubly-linked lists, so calls to Queue_next
55 * or Queue_prev can loop continuously over the Queue. The following code
56 * demonstrates one way to iterate over a Queue once from beginning to end.
57 * In this example, 'myQ' is a Queue_Handle.
58 *
59 * @p(code)
60 * Queue_Elem *elem;
61 *
62 * for (elem = Queue_head(myQ);
63 * elem != (Queue_Elem *)myQ;
64 * elem = Queue_next(elem)) {
65 * ...
66 * }
67 * @p
68 *
69 * Below is a simple example of how to create a Queue, enqueue two elements,
70 * and dequeue the elements until the queue is empty:
71 *
72 * @p(code)
73 * #include <xdc/std.h>
74 * #include <xdc/runtime/System.h>
75 *
76 * #include <ti/sysbios/knl/Queue.h>
77 *
78 * typedef struct Rec {
79 * Queue_Elem _elem;
80 * Int data;
81 * } Rec;
82 *
83 * Int main(Int argc, Char *argv[])
84 * {
85 * Queue_Handle q;
86 * Rec r1, r2;
87 * Rec* rp;
88 *
89 * r1.data = 100;
90 * r2.data = 200;
91 *
92 *
93 * // create a Queue instance 'q'
94 * q = Queue_create(NULL, NULL);
95 *
96 *
97 * // enQ a couple of records
98 * Queue_enqueue(q, &r1._elem);
99 * Queue_enqueue(q, &r2._elem);
100 *
101 *
102 * // deQ the records and print their data values until Q is empty
103 * while (!Queue_empty(q)) {
104 * rp = Queue_dequeue(q);
105 * System_printf("rec: %d\n", rp->data);
106 * }
107 *
108 * System_exit(0);
109 * return (0);
110 * }
111 * @p
112 *
113 *
114 *
115 * Unconstrained Functions
116 * All functions are unconstrained
117 *
118 * @p(html)
119 * <h3> Calling Context </h3>
120 * <table border="1" cellpadding="3">
121 * <colgroup span="1"></colgroup> <colgroup span="5" align="center">
122 * </colgroup>
123 *
124 * <tr><th> Function </th><th> Hwi </th><th> Swi </th>
125 * <th> Task </th><th> Main </th><th> Startup </th></tr>
126 * <!-- -->
127 * <tr><td> {@link #create} </td><td> N </td><td> N </td>
128 * <td> Y </td><td> Y </td><td> N </td></tr>
129 * <tr><td> {@link #insert} </td><td> Y </td><td> Y </td>
130 * <td> Y </td><td> Y </td><td> N </td></tr>
131 * <tr><td> {@link #next} </td><td> Y </td><td> Y </td>
132 * <td> Y </td><td> Y </td><td> N </td></tr>
133 * <tr><td> {@link #Params_init} </td><td> Y </td><td> Y </td>
134 * <td> Y </td><td> Y </td><td> N </td></tr>
135 * <tr><td> {@link #prev} </td><td> Y </td><td> Y </td>
136 * <td> Y </td><td> Y </td><td> N </td></tr>
137 * <tr><td> {@link #remove} </td><td> Y </td><td> Y </td>
138 * <td> Y </td><td> Y </td><td> N </td></tr>
139 * <tr><td> {@link #construct} </td><td> Y </td><td> Y </td>
140 * <td> Y </td><td> Y </td><td> N </td></tr>
141 * <tr><td> {@link #delete} </td><td> N </td><td> N </td>
142 * <td> Y </td><td> Y </td><td> N </td></tr>
143 * <tr><td> {@link #dequeue} </td><td> Y </td><td> Y </td>
144 * <td> Y </td><td> Y </td><td> N </td></tr>
145 * <tr><td> {@link #destruct} </td><td> Y </td><td> Y </td>
146 * <td> Y </td><td> Y </td><td> N </td></tr>
147 * <tr><td> {@link #empty} </td><td> Y </td><td> Y </td>
148 * <td> Y </td><td> Y </td><td> N </td></tr>
149 * <tr><td> {@link #enqueue} </td><td> Y </td><td> Y </td>
150 * <td> Y </td><td> Y </td><td> N </td></tr>
151 * <tr><td> {@link #get} </td><td> Y </td><td> Y </td>
152 * <td> Y </td><td> Y </td><td> N </td></tr>
153 * <tr><td> {@link #head} </td><td> Y </td><td> Y </td>
154 * <td> Y </td><td> Y </td><td> N </td></tr>
155 * <tr><td> {@link #put} </td><td> Y </td><td> Y </td>
156 * <td> Y </td><td> Y </td><td> N </td></tr>
157 * <tr><td colspan="6"> Definitions: <br />
158 * <ul>
159 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
160 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
161 * <li> <b>Task</b>: API is callable from a Task thread. </li>
162 * <li> <b>Main</b>: API is callable during any of these phases: </li>
163 * <ul>
164 * <li> In your module startup after this module is started
165 * (e.g. Queue_Module_startupDone() returns TRUE). </li>
166 * <li> During xdc.runtime.Startup.lastFxns. </li>
167 * <li> During main().</li>
168 * <li> During BIOS.startupFxns.</li>
169 * </ul>
170 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
171 * <ul>
172 * <li> During xdc.runtime.Startup.firstFxns.</li>
173 * <li> In your module startup before this module is started
174 * (e.g. Queue_Module_startupDone() returns FALSE).</li>
175 * </ul>
176 * </ul>
177 * </td></tr>
178 *
179 * </table>
180 * @p
181 */
182
183 @InstanceInitStatic
184 module Queue
185 {
186
187 /*!
188 * ======== BasicView ========
189 * @_nodoc
190 */
191 metaonly struct BasicView {
192 String label;
193 Ptr elems[];
194 }
195
196 /*!
197 * ======== rovViewInfo ========
198 * @_nodoc
199 */
200 @Facet
201 metaonly config ViewInfo.Instance rovViewInfo =
202 ViewInfo.create({
203 viewMap: [
204 ['Basic', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitInstance', structName: 'BasicView'}]
205 ]
206 });
207
208 /*!
209 * ======== Elem ========
210 * Opaque queue element.
211 *
212 * A field of this type is placed at the head of client structs.
213 */
214 struct Elem {
215 Elem *volatile next;
216 Elem *volatile prev;
217 };
218
219 /*!
220 * @_nodoc
221 * ======== elemClear ========
222 * Clears a Queue element's pointers so that if isQueued() is called on
223 * the element it will return FALSE. When a Queue element is dequeued or
224 * removed from a Queue, this API must be called on the element for
225 * isQueued() to return FALSE.
226 *
227 * To be clear, this API is not for removing elements from a queue, and
228 * should never be called on an element in a queue--only on dequeued
229 * elements.
230 *
231 * @param(qelem) element to be cleared
232 */
233 @DirectCall
234 Void elemClear(Elem *qelem);
235
236 /*!
237 * ======== elemClearMeta ========
238 * @_nodoc
239 * Clears a Queue element's pointers so that if isQueued() is called on
240 * the element it will return FALSE. When a Queue element is dequeued or
241 * removed from a Queue, this API must be called on the element for
242 * isQueued() to return FALSE.
243 *
244 * To be clear, this API is not for removing elements from a queue, and
245 * should never be called on an element in a queue--only on dequeued
246 * elements.
247 *
248 * @param(qelem) element to be cleared
249 */
250 metaonly Void elemClearMeta(Elem *qelem);
251
252 /*!
253 * ======== insert ========
254 * Insert `elem` in the queue in front of `qelem`.
255 *
256 * @param(qelem) element already in queue
257 *
258 * @param(elem) element to be inserted in queue
259 */
260 @DirectCall
261 Void insert(Elem *qelem, Elem *elem);
262
263 /*!
264 * ======== insertMeta ========
265 * @_nodoc
266 * Insert `elem` in the queue in front of `qelem`.
267 *
268 * @param(qelem) element already in queue
269 *
270 * @param(elem) element to be inserted in queue
271 */
272 metaonly Void insertMeta(Elem *qelem, Elem *elem);
273
274 /*!
275 * ======== next ========
276 * Return next element in queue (non-atomically).
277 *
278 * This function returns a pointer to an Elem object in the queue
279 * after `qelem`. A Queue is represented internally as a doubly-linked
280 * list, so 'next' can be called in a continuous loop over the queue.
281 * See the module description for an example of iterating once over a
282 * Queue.
283 *
284 * @param(qelem) element in queue
285 *
286 * @b(returns) next element in queue
287 */
288 @DirectCall
289 Ptr next(Elem *qelem);
290
291 /*!
292 * ======== prev ========
293 * Return previous element in queue (non-atomically).
294 *
295 * This function returns a pointer to an Elem object in the queue
296 * before `qelem`. A Queue is represented internally as a doubly-linked
297 * list, so 'prev' can be called in a continuous loop over the queue.
298 * See the module description for an example of iterating once over a
299 * Queue.
300 *
301 * @param(qelem) element in queue
302 *
303 * @b(returns) previous element in queue
304 */
305 @DirectCall
306 Ptr prev(Elem *qelem);
307
308 /*!
309 * ======== remove ========
310 * Remove qelem from middle of queue (non-atomically).
311 *
312 * The `qelem` parameter is a pointer to an existing element to be removed
313 * from the Queue.
314 *
315 * @param(qelem) element in queue
316 */
317 @DirectCall
318 Void remove (Elem *qelem);
319
320 /*!
321 * @_nodoc
322 * ======== isQueued ========
323 * Check if the elem is on any queue.
324 *
325 * In order for this API to return false on an element that has been
326 * dequeued or removed from a Queue, elemClear must have been called on
327 * the element.
328 *
329 * @param(qelem) element in queue
330 */
331 @DirectCall
332 Bool isQueued (Elem *qelem);
333
334 instance:
335
336 /*!
337 * @_nodoc
338 * Added to get the Grace instance view to work.
339 */
340 metaonly config UInt dummy = 0;
341
342 /*!
343 * ======== create ========
344 * Create a Queue object
345 */
346 @DirectCall
347 create();
348
349 /*!
350 * ======== dequeue ========
351 * Remove the element from the front of queue and return elem.
352 *
353 * @b(returns) pointer to former first element
354 */
355 @DirectCall
356 Ptr dequeue();
357
358 /*!
359 * ======== empty ========
360 * Test for an empty queue.
361 *
362 * @b(returns) TRUE if this queue is empty
363 */
364 @DirectCall
365 Bool empty();
366
367 /*!
368 * ======== enqueue ========
369 * Insert at end of queue (non-atomically).
370 *
371 * @param(elem) pointer to an element
372 */
373 @DirectCall
374 Void enqueue(Elem *elem);
375
376 /*!
377 * ======== get ========
378 * Get element from front of queue (atomically).
379 *
380 * This function removes the element from the front of queue and returns
381 * a pointer to it.
382 *
383 * @b(returns) pointer to former first element
384 */
385 @DirectCall
386 Ptr get();
387
388 /*!
389 * ======== head ========
390 * Return element at front of queue.
391 *
392 * This function returns a pointer to the element at the front of queue.
393 * The element is not removed from the queue.
394 * Returns pointer to Queue_Object if queue is empty.
395 *
396 * @b(returns) pointer to first element
397 */
398 @DirectCall
399 Ptr head();
400
401 /*!
402 * ======== headMeta ========
403 * @_nodoc
404 * Return element at front of queue. Returns null if queue is empty.
405 *
406 * This function returns a pointer to the element at the front of queue.
407 * The element is not removed from the queue.
408 *
409 * @b(returns) pointer to first element
410 */
411 metaonly Ptr headMeta();
412
413 /*!
414 * ======== put ========
415 * Put element at end of queue (atomically).
416 *
417 * @param(elem) pointer to new queue element
418 */
419 @DirectCall
420 Void put(Elem *elem);
421
422 /*!
423 * ======== putMeta ========
424 * @_nodoc
425 * Put element at end of queue.
426 *
427 * @param(elem) pointer to new queue element
428 */
429 metaonly Void putMeta(Elem* elem);
430
431 /*!
432 * ======== nextMeta ========
433 * @_nodoc
434 * Return next element in queue. Returns null if end of queue.
435 *
436 * This function returns a pointer to an Elem object in the queue
437 * after `qelem`.
438 *
439 * @param(qelem) element in queue
440 *
441 * @b(returns) next element in queue
442 */
443 metaonly Ptr nextMeta(Elem *qelem);
444
445 internal:
446
447
448 struct Instance_State {
449 Elem elem;
450 };
451 }
452 453 454 455
456