1    /* 
     2     * Copyright (c) 2012, 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 be called at runtime */
   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:   // not for client use
   446    
   447        // instance object
   448        struct Instance_State {
   449                Elem elem;
   450        };
   451    }
   452    /*
   453     *  @(#) ti.sysbios.knl; 2, 0, 0, 0,542; 2-24-2012 11:41:02; /db/vtree/library/trees/avala/avala-q28x/src/ xlibrary
   454    
   455     */
   456