The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/isci/scil/sci_abstract_list.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
    3  *
    4  * This file is provided under a dual BSD/GPLv2 license.  When using or
    5  * redistributing this file, you may do so under either license.
    6  *
    7  * GPL LICENSE SUMMARY
    8  *
    9  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
   10  *
   11  * This program is free software; you can redistribute it and/or modify
   12  * it under the terms of version 2 of the GNU General Public License as
   13  * published by the Free Software Foundation.
   14  *
   15  * This program is distributed in the hope that it will be useful, but
   16  * WITHOUT ANY WARRANTY; without even the implied warranty of
   17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   18  * General Public License for more details.
   19  *
   20  * You should have received a copy of the GNU General Public License
   21  * along with this program; if not, write to the Free Software
   22  * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
   23  * The full GNU General Public License is included in this distribution
   24  * in the file called LICENSE.GPL.
   25  *
   26  * BSD LICENSE
   27  *
   28  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
   29  * All rights reserved.
   30  *
   31  * Redistribution and use in source and binary forms, with or without
   32  * modification, are permitted provided that the following conditions
   33  * are met:
   34  *
   35  *   * Redistributions of source code must retain the above copyright
   36  *     notice, this list of conditions and the following disclaimer.
   37  *   * Redistributions in binary form must reproduce the above copyright
   38  *     notice, this list of conditions and the following disclaimer in
   39  *     the documentation and/or other materials provided with the
   40  *     distribution.
   41  *
   42  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   43  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   44  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   45  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   46  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   47  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   48  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   49  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   50  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   51  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   52  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   53  *
   54  * $FreeBSD$
   55  */
   56 /**
   57  * @file
   58  *
   59  * @brief This file contains the interface to the abstract list class.
   60  *        This class will allow for the same item to occur multiple times in
   61  *        a list or multiple lists.  It will provide an interface that is
   62  *        similar to the C++ standard template list interface.
   63  *        Methods Provided:
   64  *        - sci_abstract_list_front()
   65  *        - sci_abstract_list_back()
   66  *        - sci_abstract_list_is_empty()
   67  *        - sci_abstract_list_size()
   68  *        - sci_abstract_list_print()
   69  *        - sci_abstract_list_find()
   70  *        - sci_abstract_list_popback()
   71  *        - sci_abstract_list_popfront()
   72  *        - sci_abstract_list_erase()
   73  *        - sci_abstract_list_pushback()
   74  *        - sci_abstract_list_pushfront()
   75  *        - sci_abstract_list_get_object()
   76  *        - sci_abstract_list_get_next()
   77  *        - sci_abstract_list_insert() UNIMPLEMENTED
   78  *        - sci_abstract_list_clear()
   79  */
   80 
   81 #ifndef _SCI_ABSTRACT_LIST_H_
   82 #define _SCI_ABSTRACT_LIST_H_
   83 
   84 //******************************************************************************
   85 //*
   86 //*     I N C L U D E S
   87 //*
   88 //******************************************************************************
   89 
   90 #include <dev/isci/scil/sci_types.h>
   91 
   92 //******************************************************************************
   93 //*
   94 //*     C O N S T A N T S
   95 //*
   96 //******************************************************************************
   97 
   98 //******************************************************************************
   99 //*
  100 //*     T Y P E S
  101 //*
  102 //******************************************************************************
  103 
  104 /**
  105  * @struct SCI_ABSTRACT_ELEMENT
  106  *
  107  * @brief This object represents an element of a abstract list.
  108  *        NOTE: This structure does not evenly align on a cache line
  109  *              boundary.  If SSP specific code ends up using this list,
  110  *              then it may be a good idea to force the alignment.  Now
  111  *              it is more important to save the space.
  112  */
  113 typedef struct SCI_ABSTRACT_ELEMENT
  114 {
  115    /**
  116     * This field points to the next item in the abstract_list.
  117     */
  118    struct SCI_ABSTRACT_ELEMENT * next_p;
  119 
  120    /**
  121     * This field points to the previous item in the abstract_list.
  122     */
  123    struct SCI_ABSTRACT_ELEMENT * previous_p;
  124 
  125    /**
  126     * This field points to the object the list is managing (i.e. the thing
  127     * being listed).
  128     */
  129    void * object_p;
  130 
  131 } SCI_ABSTRACT_ELEMENT_T;
  132 
  133 /**
  134  * @struct SCI_ABSTRACT_ELEMENT_LIST
  135  *
  136  * @brief This object represents an element list object.  It can have
  137  *        elements added and removed from it.
  138  */
  139 typedef struct SCI_ABSTRACT_ELEMENT_LIST
  140 {
  141    /**
  142     * Pointer to the front (head) of the list.
  143     */
  144    SCI_ABSTRACT_ELEMENT_T * front_p;
  145 
  146    /**
  147     * Pointer to the back (tail) of the list.
  148     */
  149    SCI_ABSTRACT_ELEMENT_T * back_p;
  150 
  151    /**
  152     * This field depicts the number of elements in this list.
  153     * NOTE: It is possible to remove this field and replace it with a
  154     *       linear walking of the list to determine the size, but since
  155     *       there aren't many lists in the system we don't utilize much
  156     *       space.
  157     */
  158    U32 size;
  159 
  160 } SCI_ABSTRACT_ELEMENT_LIST_T;
  161 
  162 /**
  163  * @struct SCI_ABSTRACT_ELEMENT_POOL
  164  *
  165  * @brief This structure provides the pool of free abstract elements to be
  166  *        utilized by an SCI_ABSTRACT_LIST.
  167  */
  168 typedef struct SCI_ABSTRACT_ELEMENT_POOL
  169 {
  170    /**
  171     * Pointer to an array of elements to be managed by this pool.  This
  172     * array acts as the memory store for the elements in the free pool or
  173     * allocated out of the pool into an SCI_ABSTRACT_LIST.
  174     */
  175    SCI_ABSTRACT_ELEMENT_T * elements;
  176 
  177    /**
  178     * This field contains the maximum number of free elements for the pool.
  179     * It is set at creation of the pool and should not be changed afterward.
  180     */
  181    U32 max_elements;
  182 
  183    /**
  184     * Pointer to the list of free elements that can be allocated from
  185     * the pool.
  186     */
  187    struct SCI_ABSTRACT_ELEMENT_LIST  free_list;
  188 
  189 } SCI_ABSTRACT_ELEMENT_POOL_T;
  190 
  191 /**
  192  * @struct SCI_ABSTRACT_LIST
  193  *
  194  * @brief This object provides the ability to queue any type of object or
  195  *        even the same object multiple times.  The object must be provided
  196  *        an element pool from which to draw free elements.
  197  */
  198 typedef struct SCI_ABSTRACT_LIST
  199 {
  200    /**
  201     * This represents the elements currently managed by the list.
  202     */
  203    SCI_ABSTRACT_ELEMENT_LIST_T  elements;
  204 
  205    /**
  206     * This field contains elements that are currently available for
  207     * allocation into the list of elements;
  208     */
  209    SCI_ABSTRACT_ELEMENT_POOL_T * free_pool;
  210 
  211 } SCI_ABSTRACT_LIST_T;
  212 
  213 //******************************************************************************
  214 //*
  215 //*     P R O T E C T E D   M E T H O D S
  216 //*
  217 //******************************************************************************
  218 
  219 void sci_abstract_element_pool_construct(
  220    SCI_ABSTRACT_ELEMENT_POOL_T * pool,
  221    SCI_ABSTRACT_ELEMENT_T      * list_elements,
  222    int                           element_count
  223 );
  224 
  225 void sci_abstract_list_construct(
  226    SCI_ABSTRACT_LIST_T         * list,
  227    SCI_ABSTRACT_ELEMENT_POOL_T * free_pool
  228 );
  229 
  230 
  231 
  232 #ifdef USE_ABSTRACT_LIST_FUNCTIONS
  233 //******************************************************************************
  234 //*
  235 //*     P U B L I C   M E T H O D S
  236 //*
  237 //******************************************************************************
  238 
  239 /**
  240  * Simply return the front element pointer of the list.  This returns an element
  241  * element as opposed to what the element is pointing to.
  242  */
  243 SCI_ABSTRACT_ELEMENT_T * sci_abstract_list_get_front(
  244    SCI_ABSTRACT_LIST_T * list_p
  245 );
  246 
  247 
  248 /**
  249  * This method simply returns the object pointed to by the head (front) of
  250  * the list.
  251  */
  252 void * sci_abstract_list_front(
  253    SCI_ABSTRACT_LIST_T * list_p
  254 );
  255 
  256 
  257 /**
  258  * This method simply returns the object pointed to by the tail (back) of
  259  * the list.
  260  */
  261 void * sci_abstract_list_back(
  262    SCI_ABSTRACT_LIST_T * list_p
  263 );
  264 
  265 
  266 /**
  267  * This method will return FALSE if the list is not empty.
  268  */
  269 BOOL sci_abstract_list_is_empty(
  270    SCI_ABSTRACT_LIST_T * list_p
  271 );
  272 
  273 
  274 /**
  275  * This method will return the number of elements queued in the list.
  276  */
  277 U32 sci_abstract_list_size(
  278    SCI_ABSTRACT_LIST_T * list_p
  279 );
  280 
  281 
  282 /**
  283  * This method simply returns the next list element in the list.
  284  */
  285 SCI_ABSTRACT_ELEMENT_T * sci_abstract_list_get_next(
  286    SCI_ABSTRACT_ELEMENT_T * alElement_p
  287 );
  288 
  289 
  290 /**
  291  * This method simply prints the contents of the list.
  292  */
  293 void  sci_abstract_list_print(
  294    SCI_ABSTRACT_LIST_T * list_p
  295 );
  296 
  297 
  298 /**
  299  * This method will simply search the supplied list for the desired object.
  300  * It will return a pointer to the object, if it is found.  Otherwise
  301  * it will return NULL.
  302  */
  303 void * sci_abstract_list_find(
  304    SCI_ABSTRACT_LIST_T * list_p,
  305    void * obj_p
  306 );
  307 
  308 
  309 /**
  310  * This method will simply remove the element at the back (tail) of the list.
  311  * It will return a pointer to the object that was removed or NULL if not
  312  * found.
  313  */
  314 void * sci_abstract_list_popback(
  315    SCI_ABSTRACT_LIST_T * list_p
  316 );
  317 
  318 
  319 /**
  320  * This method simply removes the list element at the head of the list
  321  * and returns the pointer to the object that was removed.
  322  */
  323 void * sci_abstract_list_popfront(
  324    SCI_ABSTRACT_LIST_T * list_p
  325 );
  326 
  327 
  328 
  329 /**
  330  * This method will erase (remove) all instances of the supplied object from
  331  * anywhere in the list.
  332  */
  333 void sci_abstract_list_erase(
  334    SCI_ABSTRACT_LIST_T * list_p,
  335    void * obj_p
  336 );
  337 
  338 
  339 /**
  340  * This method simply adds a LIST_ELEMENT for the supplied object to the back
  341  * (tail) of the supplied list.
  342  */
  343 void sci_abstract_list_pushback(
  344    SCI_ABSTRACT_LIST_T * list_p,
  345    void * obj_p
  346 );
  347 
  348 
  349 
  350 /**
  351  * This method simply adds a LIST_ELEMENT for the supplied object to the front
  352  * (head) of the supplied list.
  353  */
  354 void sci_abstract_list_pushfront(
  355    SCI_ABSTRACT_LIST_T * list_p,
  356    void * obj_p
  357 );
  358 
  359 
  360 /**
  361  * This method will add the objToAdd_p object to the list before the obj_p.
  362  * NOTE: UNIMPLEMENTED
  363  */
  364 void sci_abstract_list_insert(
  365    SCI_ABSTRACT_LIST_T * list_p,
  366    void * obj_p,
  367    void * objToAdd_p
  368 );
  369 
  370 
  371 /**
  372  * This method simply frees all the items from the list.
  373  */
  374 void sci_abstract_list_clear(
  375    SCI_ABSTRACT_LIST_T * list_p
  376 );
  377 
  378 
  379 /**
  380  * This method simply returns the object being pointed to by the list element
  381  * (The item being listed).
  382  */
  383 void * sci_abstract_list_get_object(
  384    SCI_ABSTRACT_ELEMENT_T * alElement_p
  385 );
  386 
  387 
  388 /**
  389  * This method is simply a wrapper to provide the number of elements in
  390  * the free list.
  391  */
  392 U32 sci_abstract_list_freeList_size(
  393    SCI_ABSTRACT_LIST_T * freeList
  394 );
  395 
  396 
  397 //******************************************************************************
  398 //*
  399 //*     P R I V A T E   M E T H O D S
  400 //*
  401 //******************************************************************************
  402 
  403 /**
  404  * This method simply performs the common portion of pushing a list element
  405  * onto a list.
  406  *
  407  * WARNING: This is a private helper method that should not be called directly
  408  *          by any users.
  409  */
  410 void private_push_front(
  411    SCI_ABSTRACT_ELEMENT_LIST_T * privateList_p,
  412    SCI_ABSTRACT_ELEMENT_T * alElement_p
  413 );
  414 
  415 
  416 /**
  417  * This method simply performs the common portion of popping a list element
  418  * from a list.
  419  *
  420  * WARNING: This is a private helper method that should not be called directly
  421  *          by any users.
  422  */
  423 SCI_ABSTRACT_ELEMENT_T * private_pop_front(
  424    SCI_ABSTRACT_ELEMENT_LIST_T * privateList_p
  425 );
  426 
  427 
  428 /**
  429  * This method will simply search the supplied list for the desired object.
  430  * It will return a pointer to the abstract_list_element if found, otherwise
  431  * it will return NULL.
  432  */
  433 SCI_ABSTRACT_ELEMENT_T * private_find(
  434    SCI_ABSTRACT_ELEMENT_LIST_T * list_p,
  435    void * obj_p
  436 );
  437 
  438 
  439 /**
  440  * This private method will free the supplied list element back to the pool
  441  * of free list elements.
  442  */
  443 void private_pool_free(
  444    SCI_ABSTRACT_ELEMENT_POOL_T * free_pool,
  445    SCI_ABSTRACT_ELEMENT_T * alElement_p
  446 );
  447 
  448 
  449 /**
  450  * This private method will allocate a list element from the pool of free
  451  * list elements.
  452  */
  453 SCI_ABSTRACT_ELEMENT_T * private_pool_allocate(
  454    SCI_ABSTRACT_ELEMENT_POOL_T * free_pool
  455 );
  456 
  457 
  458 #else
  459 
  460 //******************************************************************************
  461 //*
  462 //*     P U B L I C   M E T H O D S
  463 //*
  464 //******************************************************************************
  465 
  466 /**
  467  * Simply return the front element pointer of the list.  This returns an element
  468  * element as opposed to what the element is pointing to.
  469  */
  470 #define sci_abstract_list_get_front(                                           \
  471    list_p                                                                      \
  472 )                                                                              \
  473 ((list_p)->elements.front_p)
  474 
  475 /**
  476  * This method simply returns the object pointed to by the head (front) of
  477  * the list.
  478  */
  479 #define sci_abstract_list_front(                                               \
  480    list_p                                                                      \
  481 )                                                                              \
  482 ( ( (list_p)->elements.front_p ) ? ((list_p)->elements.front_p->object_p) : NULL )
  483 
  484 /**
  485  * This method simply returns the object pointed to by the tail (back) of
  486  * the list.
  487  */
  488 #define sci_abstract_list_back(                                                \
  489    list_p                                                                      \
  490 )                                                                              \
  491 ( ( (list_p)->elements.back_p ) ? ((list_p)->elements.back_p->object_p) : NULL )
  492 
  493 /**
  494  * This method will return FALSE if the list is not empty.
  495  */
  496 #define sci_abstract_list_is_empty(                                            \
  497    list_p                                                                      \
  498 )                                                                              \
  499 ( (list_p)->elements.front_p == NULL )
  500 
  501 /**
  502  * This method will return the number of elements queued in the list.
  503  */
  504 #define sci_abstract_list_size(                                                \
  505    list_p                                                                      \
  506 )                                                                              \
  507 ( (list_p)->elements.size )
  508 
  509 /**
  510  * This method simply returns the next list element in the list.
  511  */
  512 #define sci_abstract_list_get_next(                                            \
  513    alElement_p                                                                 \
  514 )                                                                              \
  515 ( (alElement_p)->next_p )
  516 
  517 /**
  518  * This method simply prints the contents of the list.
  519  */
  520 #define sci_abstract_list_print(                                               \
  521    list_p                                                                      \
  522 )                                                                              \
  523 {                                                                              \
  524    SCI_ABSTRACT_ELEMENT_T * alElement_p = list_p->elements.front_p;            \
  525                                                                                \
  526    while (alElement_p != NULL)                                                 \
  527    {                                                                           \
  528       /* Check to see if we found the object for which we are searching. */    \
  529       printf("ITEM next_p 0x%x prev_p 0x%x obj_p 0x%x, 0x%x\n",                \
  530              alElement_p->next_p,                                              \
  531              alElement_p->previous_p,                                          \
  532              (U32*) (alElement_p->object_p));                                  \
  533                                                                                \
  534       alElement_p = alElement_p->next_p;                                       \
  535    }                                                                           \
  536 }
  537 
  538 /**
  539  * This method will simply search the supplied list for the desired object.
  540  * It will return a pointer to the object, if it is found.  Otherwise
  541  * it will return NULL.
  542  */
  543 #define sci_abstract_list_find(                                                \
  544    list_p,                                                                     \
  545    obj_p                                                                       \
  546 )                                                                              \
  547 ({                                                                             \
  548    sci_abstract_list_get_object(private_find(&(list_p)->elements, (obj_p)));   \
  549 })
  550 
  551 /**
  552  * This method will simply remove the element at the back (tail) of the list.
  553  * It will return a pointer to the object that was removed or NULL if not
  554  * found.
  555  */
  556 #define sci_abstract_list_popback(                                             \
  557    list_p                                                                      \
  558 )                                                                              \
  559 ({                                                                             \
  560    SCI_ABSTRACT_ELEMENT_LIST_T * elem_list = &(list_p)->elements;              \
  561    SCI_ABSTRACT_ELEMENT_T      * alElement_p = elem_list->back_p;              \
  562    void * obj_p = NULL;                                                        \
  563                                                                                \
  564    if (alElement_p != NULL)                                                    \
  565    {                                                                           \
  566       obj_p = alElement_p->object_p;                                           \
  567       if (elem_list->back_p == elem_list->front_p)                             \
  568       {                                                                        \
  569          elem_list->back_p = elem_list->front_p = NULL;                        \
  570       }                                                                        \
  571       else                                                                     \
  572       {                                                                        \
  573          elem_list->back_p = elem_list->back_p->previous_p;                    \
  574          elem_list->back_p->next_p = NULL;                                     \
  575       }                                                                        \
  576                                                                                \
  577       elem_list->size--;                                                       \
  578       private_pool_free((list_p)->free_pool, alElement_p);                     \
  579    }                                                                           \
  580                                                                                \
  581    obj_p;                                                                      \
  582 })
  583 
  584 /**
  585  * This method simply removes the list element at the head of the list
  586  * and returns the pointer to the object that was removed.
  587  */
  588 #define sci_abstract_list_popfront(                                            \
  589    list_p                                                                      \
  590 )                                                                              \
  591 ({                                                                             \
  592    SCI_ABSTRACT_ELEMENT_T * alElement_p =                                      \
  593                               private_pop_front(&(list_p)->elements);          \
  594    void * obj_p = NULL;                                                        \
  595                                                                                \
  596    if (alElement_p != NULL)                                                    \
  597    {                                                                           \
  598       obj_p = alElement_p->object_p;                                           \
  599       private_pool_free((list_p)->free_pool, alElement_p);                     \
  600    }                                                                           \
  601                                                                                \
  602    obj_p;                                                                      \
  603 })
  604 
  605 /**
  606  * This method will erase (remove) all instances of the supplied object from
  607  * anywhere in the list.
  608  */
  609 #define sci_abstract_list_erase(                                               \
  610    list_p,                                                                     \
  611    obj_p                                                                       \
  612 )                                                                              \
  613 {                                                                              \
  614    SCI_ABSTRACT_ELEMENT_LIST_T * elem_list = &(list_p)->elements;              \
  615    SCI_ABSTRACT_ELEMENT_T      * alElement_p;                                  \
  616                                                                                \
  617    while ((alElement_p = private_find(elem_list, (obj_p))) != NULL)            \
  618    {                                                                           \
  619       if (alElement_p == elem_list->front_p)                                   \
  620       {                                                                        \
  621          sci_abstract_list_popfront(list_p);                                   \
  622       }                                                                        \
  623       else if (alElement_p == elem_list->back_p)                               \
  624       {                                                                        \
  625          sci_abstract_list_popback(list_p);                                    \
  626       }                                                                        \
  627       else                                                                     \
  628       {                                                                        \
  629          alElement_p->previous_p->next_p = alElement_p->next_p;                \
  630          alElement_p->next_p->previous_p = alElement_p->previous_p;            \
  631          elem_list->size--;                                                    \
  632          private_pool_free((list_p)->free_pool, alElement_p);                  \
  633       }                                                                        \
  634    }                                                                           \
  635 }
  636 
  637 /**
  638  * This method simply adds a LIST_ELEMENT for the supplied object to the back
  639  * (tail) of the supplied list.
  640  */
  641 #define sci_abstract_list_pushback(                                            \
  642    list_p,                                                                     \
  643    obj_p                                                                       \
  644 )                                                                              \
  645 {                                                                              \
  646    SCI_ABSTRACT_ELEMENT_LIST_T * elem_list = &(list_p)->elements;              \
  647    SCI_ABSTRACT_ELEMENT_T      * alElement_p                                   \
  648       = private_pool_allocate((list_p)->free_pool);                            \
  649    assert(alElement_p != NULL);                                                \
  650                                                                                \
  651    alElement_p->object_p = (obj_p);                                            \
  652                                                                                \
  653    if (elem_list->front_p == NULL)                                             \
  654    {                                                                           \
  655       elem_list->front_p = elem_list->back_p = alElement_p;                    \
  656    }                                                                           \
  657    else                                                                        \
  658    {                                                                           \
  659       elem_list->back_p->next_p = alElement_p;                                 \
  660       alElement_p->previous_p   = elem_list->back_p;                           \
  661       elem_list->back_p         = alElement_p;                                 \
  662    }                                                                           \
  663                                                                                \
  664    elem_list->size++;                                                          \
  665 }
  666 
  667 /**
  668  * This method simply adds a LIST_ELEMENT for the supplied object to the front
  669  * (head) of the supplied list.
  670  */
  671 #define sci_abstract_list_pushfront(                                           \
  672    list_p,                                                                     \
  673    obj_p                                                                       \
  674 )                                                                              \
  675 {                                                                              \
  676    SCI_ABSTRACT_ELEMENT_T * alElement_p =                                      \
  677          private_pool_allocate((list_p)->free_pool);                           \
  678    alElement_p->object_p = (obj_p);                                            \
  679    private_push_front(&(list_p)->elements, alElement_p);                       \
  680 }
  681 
  682 /**
  683  * This method will add the objToAdd_p object to the list before the obj_p.
  684  * NOTE: UNIMPLEMENTED
  685  */
  686 #define sci_abstract_list_insert(                                              \
  687    list_p,                                                                     \
  688    obj_p,                                                                      \
  689    objToAdd_p                                                                  \
  690 )                                                                              \
  691 {                                                                              \
  692    SCI_ABSTRACT_ELEMENT_LIST_T * elem_list = &(list_p)->elements;              \
  693                                                                                \
  694    SCI_ABSTRACT_ELEMENT_T * obj_element = private_find(elem_list, obj_p);      \
  695                                                                                \
  696    SCI_ABSTRACT_ELEMENT_T * objToAdd_element =                                 \
  697       private_pool_allocate((list_p)->free_pool);                              \
  698                                                                                \
  699    objToAdd_element->object_p = objToAdd_p;                                    \
  700                                                                                \
  701    ASSERT(obj_element != NULL);                                                \
  702    ASSERT(objToAdd_element != NULL);                                           \
  703                                                                                \
  704    if (obj_element == elem_list->front_p)                                      \
  705    {                                                                           \
  706       objToAdd_element->object_p = (objToAdd_p);                               \
  707       private_push_front(&(list_p)->elements, objToAdd_element);               \
  708    }                                                                           \
  709    else                                                                        \
  710    {                                                                           \
  711       obj_element->previous_p->next_p = objToAdd_element;                      \
  712       objToAdd_element->previous_p = obj_element->previous_p;                  \
  713                                                                                \
  714       obj_element->previous_p = objToAdd_element;                              \
  715       objToAdd_element->next_p = obj_element;                                  \
  716                                                                                \
  717       elem_list->size++;                                                       \
  718    }                                                                           \
  719 }
  720 
  721 /**
  722  * This method simply frees all the items from the list.
  723  */
  724 #define sci_abstract_list_clear(                                               \
  725    list_p                                                                      \
  726 )                                                                              \
  727 {                                                                              \
  728    while ((list_p)->elements.size > 0)                                         \
  729       sci_abstract_list_popfront((list_p));                                    \
  730 }
  731 
  732 /**
  733  * This method simply returns the object being pointed to by the list element
  734  * (The item being listed).
  735  */
  736 #define sci_abstract_list_get_object(                                          \
  737    alElement_p                                                                 \
  738 )                                                                              \
  739 ({                                                                             \
  740    void * obj_p = NULL;                                                        \
  741    if ((alElement_p) != NULL)                                                  \
  742       obj_p = (alElement_p)->object_p;                                         \
  743                                                                                \
  744    obj_p;                                                                      \
  745 })
  746 
  747 /**
  748  * This method is simply a wrapper to provide the number of elements in
  749  * the free list.
  750  */
  751 #define sci_abstract_list_freeList_size(freeList) (sci_abstract_list_size(freeList))
  752 
  753 //******************************************************************************
  754 //*
  755 //*     P R I V A T E   M E T H O D S
  756 //*
  757 //******************************************************************************
  758 
  759 /**
  760  * This method simply performs the common portion of pushing a list element
  761  * onto a list.
  762  *
  763  * WARNING: This is a private helper method that should not be called directly
  764  *          by any users.
  765  */
  766 #define private_push_front(                                                    \
  767    privateList_p,                                                              \
  768    alElement_p                                                                 \
  769 )                                                                              \
  770 {                                                                              \
  771    if ((privateList_p)->front_p == NULL)                                       \
  772    {                                                                           \
  773       (privateList_p)->front_p = (privateList_p)->back_p = (alElement_p);      \
  774       (alElement_p)->next_p = (alElement_p)->previous_p = NULL;                \
  775    }                                                                           \
  776    else                                                                        \
  777    {                                                                           \
  778       (alElement_p)->next_p                = (privateList_p)->front_p;         \
  779       (alElement_p)->previous_p            = NULL;                             \
  780       (privateList_p)->front_p->previous_p = (alElement_p);                    \
  781       (privateList_p)->front_p             = (alElement_p);                    \
  782    }                                                                           \
  783                                                                                \
  784    (privateList_p)->size++;                                                    \
  785 }
  786 
  787 /**
  788  * This method simply performs the common portion of popping a list element
  789  * from a list.
  790  *
  791  * WARNING: This is a private helper method that should not be called directly
  792  *          by any users.
  793  */
  794 #define private_pop_front(                                                     \
  795    privateList_p                                                               \
  796 )                                                                              \
  797 ({                                                                             \
  798    SCI_ABSTRACT_ELEMENT_T * alElement_p = (privateList_p)->front_p;            \
  799                                                                                \
  800    if (alElement_p != NULL)                                                    \
  801    {                                                                           \
  802       if ((privateList_p)->front_p == (privateList_p)->back_p)                 \
  803       {                                                                        \
  804          (privateList_p)->front_p = (privateList_p)->back_p = NULL;            \
  805       }                                                                        \
  806       else                                                                     \
  807       {                                                                        \
  808          (privateList_p)->front_p = (privateList_p)->front_p->next_p;          \
  809          (privateList_p)->front_p->previous_p = NULL;                          \
  810       }                                                                        \
  811                                                                                \
  812       (privateList_p)->size--;                                                 \
  813    }                                                                           \
  814                                                                                \
  815    alElement_p;                                                                \
  816 })
  817 
  818 /**
  819  * This method will simply search the supplied list for the desired object.
  820  * It will return a pointer to the abstract_list_element if found, otherwise
  821  * it will return NULL.
  822  */
  823 #define private_find(                                                          \
  824    list_p,                                                                     \
  825    obj_p                                                                       \
  826 )                                                                              \
  827 ({                                                                             \
  828    SCI_ABSTRACT_ELEMENT_T * alElement_p = (list_p)->front_p;                   \
  829                                                                                \
  830    while (alElement_p != NULL)                                                 \
  831    {                                                                           \
  832       /* Check to see if we found the object for which we are searching. */    \
  833       if (alElement_p->object_p == (void*) (obj_p))                            \
  834       {                                                                        \
  835          break;                                                                \
  836       }                                                                        \
  837                                                                                \
  838       alElement_p = alElement_p->next_p;                                       \
  839    }                                                                           \
  840                                                                                \
  841    alElement_p;                                                                \
  842 })
  843 
  844 /**
  845  * This private method will free the supplied list element back to the pool
  846  * of free list elements.
  847  */
  848 #define private_pool_free(                                                     \
  849    free_pool,                                                                  \
  850    alElement_p                                                                 \
  851 )                                                                              \
  852 {                                                                              \
  853    /* Push the list element back to the head to get better locality of */      \
  854    /* reference with the cache.                                        */      \
  855    private_push_front(&(free_pool)->free_list, (alElement_p));                 \
  856 }
  857 
  858 /**
  859  * This private method will allocate a list element from the pool of free
  860  * list elements.
  861  */
  862 #define private_pool_allocate(free_pool)                                       \
  863 ({                                                                             \
  864    SCI_ABSTRACT_ELEMENT_T * alElement_p;                                       \
  865                                                                                \
  866    alElement_p = private_pop_front(&(free_pool)->free_list);                   \
  867                                                                                \
  868    memset(alElement_p, 0, sizeof(SCI_ABSTRACT_ELEMENT_T));                     \
  869    alElement_p;                                                                \
  870 })
  871 
  872 #endif
  873 #endif // _ABSTRACT_LIST_H_

Cache object: 54e046f01d208080f1dbbc1d428857a8


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.