1 /*
2 * Copyright (c) 2011, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 * */
32 /*
33 * ======== Queue.xdc ========
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 /* Construct/Destruct CAN becalled at runtime */
184 module Queue
185 {
186
187 /*!
188 * ======== BasicView ========
189 * @_nodoc 190 */
191 metaonlystruct BasicView {
192 String label;
193 Ptr elems[];
194 }
195
196 /*!
197 * ======== rovViewInfo ========
198 * @_nodoc 199 */
200 @Facet
201 metaonlyconfig 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 * ======== dequeue ========
338 * Remove the element from the front of queue and return elem.
339 *
340 * @b(returns) pointer to former first element
341 */
342 @DirectCall
343 Ptr dequeue();
344
345 /*!
346 * ======== empty ========
347 * Test for an empty queue.
348 *
349 * @b(returns) TRUE if this queue is empty
350 */
351 @DirectCall
352 Bool empty();
353
354 /*!
355 * ======== enqueue ========
356 * Insert at end of queue (non-atomically).
357 *
358 * @param(elem) pointer to an element
359 */
360 @DirectCall
361 Void enqueue(Elem *elem);
362
363 /*!
364 * ======== get ========
365 * Get element from front of queue (atomically).
366 *
367 * This function removes the element from the front of queue and returns
368 * a pointer to it.
369 *
370 * @b(returns) pointer to former first element
371 */
372 @DirectCall
373 Ptr get();
374
375 /*!
376 * ======== head ========
377 * Return element at front of queue.
378 *
379 * This function returns a pointer to the element at the front of queue.
380 * The element is not removed from the queue.
381 * Returns pointer to Queue_Object if queue is empty.
382 *
383 * @b(returns) pointer to first element
384 */
385 @DirectCall
386 Ptr head();
387
388 /*!
389 * ======== headMeta ========
390 * @_nodoc 391 * Return element at front of queue. Returns null if queue is empty.
392 *
393 * This function returns a pointer to the element at the front of queue.
394 * The element is not removed from the queue.
395 *
396 * @b(returns) pointer to first element
397 */
398 metaonly Ptr headMeta();
399
400 /*!
401 * ======== put ========
402 * Put element at end of queue (atomically).
403 *
404 * @param(elem) pointer to new queue element
405 */
406 @DirectCall
407 Void put(Elem *elem);
408
409 /*!
410 * ======== putMeta ========
411 * @_nodoc 412 * Put element at end of queue.
413 *
414 * @param(elem) pointer to new queue element
415 */
416 metaonly Void putMeta(Elem* elem);
417
418 /*!
419 * ======== nextMeta ========
420 * @_nodoc 421 * Return next element in queue. Returns null if end of queue.
422 *
423 * This function returns a pointer to an Elem object in the queue
424 * after `qelem`.
425 *
426 * @param(qelem) element in queue
427 *
428 * @b(returns) next element in queue
429 */
430 metaonly Ptr nextMeta(Elem *qelem);
431
432 internal: // not for client use
433
434 // instance object
435 struct Instance_State {
436 Elem elem;
437 };
438 }
439 /*
440 * @(#) ti.sysbios.knl; 2, 0, 0, 0,534; 12-21-2011 15:08:56; /db/vtree/library/trees/avala/avala-q22x/src/ xlibrary
441 442 */
443