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_fast_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 #ifndef _SCI_FAST_LIST_HEADER_
   57 #define _SCI_FAST_LIST_HEADER_
   58 
   59 /**
   60  * @file
   61  *
   62  * @brief Header file that contains basic Linked List manipulation macros.
   63  *        These macros implement a double linked list (SCI_FAST_LIST_T) that is
   64  *        circular in nature.  This means that the next and prev pointers for
   65  *        an empty queue head always the address of the queue head
   66  *        SCI_FAST_LIST_T.  Likewise an element that has been removed from
   67  *        a queue will have its next and prev pointer set to the address of
   68  *        the SCI_FAST_LIST_T found in the structure just removed from the
   69  *        queue.   Pointers in this implementation never == NULL.
   70  *
   71  *        Definitions:
   72  *        - anchor : This is the list container and has a
   73  *                   pointer to both the head and tail of the
   74  *                   list elements
   75  *        - element: This is the list element not the actual
   76  *                   object but the list element which has a
   77  *                   pointer to the object.
   78  */
   79 
   80 //******************************************************************************
   81 //*
   82 //*     P U B L I C   M E T H O D S
   83 //*
   84 //******************************************************************************
   85 
   86 /**
   87  * Initialize the double linked list anchor.  The other macros require the list
   88  * anchor to be set up using this macro.
   89  */
   90 #define sci_fast_list_init(anchor)                                            \
   91 {                                                                             \
   92    (anchor)->list_head = NULL;                                                \
   93    (anchor)->list_tail = NULL;                                                \
   94    (anchor)->element_count = 0;                                               \
   95 }
   96 
   97 /**
   98  * Initialize the sci_fast_list_element to point to its owning object
   99  */
  100 #define sci_fast_list_element_init(list_object, element)                      \
  101 {                                                                             \
  102    (element)->object = (list_object);                                         \
  103    (element)->next = (element)->prev = NULL;                                  \
  104    (element)->owning_list = NULL;                                             \
  105 }
  106 
  107 /**
  108  * See if there is anything on the list by checking the list anchor.
  109  */
  110 #define sci_fast_list_is_empty(anchor) ((anchor)->list_head == NULL)
  111 
  112 /**
  113  * Return a pointer to the element at the head of the sci_fast_list.  The
  114  * item is NOT removed from the list.
  115  *
  116  * NOTE: This macro will always return a value, even if the list is empty.
  117  *       You must insure the list is not empty or use Dlist_safeGetHead.
  118  *
  119  * element - A pointer into which to save the address of the structure
  120  *           containing the SCI_FAST_LIST at the list head.
  121  */
  122 #define sci_fast_list_get_head(anchor)                                        \
  123    ((anchor)->list_head == NULL ? NULL: (anchor)->list_head->object)
  124 
  125 /**
  126  * Return a pointer to the element at the tail of the sci_fast_list.  The item
  127  * is NOT removed from the list.
  128  *
  129  * NOTE: This macro will always return a value, even if the list is empty.
  130  *       You must insure the list is not empty or use Dlist_safeGetHead.
  131  *
  132  * element - A pointer into which to save the address of the structure
  133  *           containing the SCI_FAST_LIST at the list head.
  134  */
  135 #define sci_fast_list_get_tail(anchor)                                        \
  136    ((anchor)->list_tail == NULL ? NULL: (anchor)->list_head->object)
  137 
  138 /**
  139  * This method will get the next dListField in the SCI_FAST_LIST.  This method
  140  * returns a pointer to a SCI_FAST_LIST object.
  141  */
  142 #define sci_fast_list_get_next(element) ((element)->next)
  143 
  144 /**
  145  * This method will get the prev dListField in the SCI_FAST_LIST.  This method
  146  * returns a pointer to a SCI_FAST_LIST object.
  147  */
  148 #define sci_fast_list_get_prev(element) ((element)->prev)
  149 
  150 
  151 /**
  152  * This method returns the object that is represented by this
  153  * sci_fast_list_element
  154  */
  155 #define sci_fast_list_get_object(element) ((element)->object)
  156 
  157 /**
  158  * This method will determine if the supplied dListField is on a SCI_FAST_LIST.
  159  * If the element has only one dListField but can be on more than one list,
  160  * this will only tell you that it is on one of them.  If the element has
  161  * multiple dListFields and can exist on multiple lists at the same time, this
  162  * macro can tell you exactly which list it is on.
  163  */
  164 #define sci_fast_list_is_on_a_list(element) ((element)->owning_list != NULL)
  165 
  166 /**
  167  * This method will determine if the supplied dListFieldName is on the given
  168  * specified list?  If the element can be on more than one list, this
  169  * allows you to determine exactly which list it is on.  Performs a linear
  170  * search through the list.
  171  * result - BOOL_T that will contain the result of the search.
  172  *          TRUE - item is on the list described by head.
  173  *          FALSE - item is not on the list.
  174  */
  175 #define sci_fast_list_is_on_this_list(anchor, element) \
  176    ((element)->owning_list == (anchor))
  177 
  178 //******************************************************************************
  179 //*
  180 //*     T Y P E S
  181 //*
  182 //******************************************************************************
  183 
  184 /**
  185  * @struct SCI_FAST_LIST
  186  *
  187  * @brief the list owner or list anchor for a set of SCI_FAST_LIST
  188  *        elements.
  189  */
  190 typedef struct SCI_FAST_LIST
  191 {
  192    struct SCI_FAST_LIST_ELEMENT *list_head;
  193    struct SCI_FAST_LIST_ELEMENT *list_tail;
  194    int                           element_count;
  195 } SCI_FAST_LIST_T;
  196 
  197 /**
  198  * @struct SCI_FAST_LIST_ELEMENT
  199  *
  200  * @brief This structure defines what a doubly linked list element contains.
  201  */
  202 typedef struct SCI_FAST_LIST_ELEMENT
  203 {
  204    struct SCI_FAST_LIST_ELEMENT *next;
  205    struct SCI_FAST_LIST_ELEMENT *prev;
  206    struct SCI_FAST_LIST         *owning_list;
  207    void                         *object;
  208 } SCI_FAST_LIST_ELEMENT_T;
  209 
  210 
  211 /**
  212  * Insert an element to be the new head of the list hanging off of the list
  213  * anchor.  An empty list has the list anchor pointing to itself.
  214  * dListAnchor - The name of the SCI_FAST_LIST_T element that is the anchor
  215  *               of the queue.
  216  * dListFieldBeingInserted - The SCI_FAST_LIST_T field in the data structure
  217  *                           being queued.  This SCI_FAST_LIST will become
  218  *                           the new list head.
  219  */
  220 INLINE
  221 static void sci_fast_list_insert_head(
  222     SCI_FAST_LIST_T *anchor,
  223     SCI_FAST_LIST_ELEMENT_T *element
  224 )
  225 {
  226     element->owning_list = anchor;
  227     element->prev = NULL;
  228     if ( anchor->list_head == NULL )
  229         anchor->list_tail = element;
  230     else
  231         anchor->list_head->prev = element;
  232     element->next = anchor->list_head;
  233     anchor->list_head = element;
  234     anchor->element_count++;
  235 }
  236 
  237 /**
  238  * Insert an element at the tail of the list.  Since the list is circular we
  239  * can add the element at the tail through use the list anchors previous
  240  * pointer.
  241  * dListAnchor - The name of the SCI_FAST_LIST_T element that is the anchor
  242  *               of the queue.
  243  * dListFieldBeingInserted - The SCI_FAST_LIST_T field in the data structure
  244  *                           being queued.  This SCI_FAST_LIST will become
  245  *                           the new list head.
  246  */
  247 INLINE
  248 static void sci_fast_list_insert_tail(
  249     SCI_FAST_LIST_T *anchor,
  250     SCI_FAST_LIST_ELEMENT_T *element
  251 )
  252 {
  253     element->owning_list = anchor;
  254     element->next = NULL;
  255     if ( anchor->list_tail == NULL ) {
  256         anchor->list_head = element;
  257     } else {
  258         anchor->list_tail->next = element;
  259     }
  260     element->prev = anchor->list_tail;
  261     anchor->list_tail = element;
  262     anchor->element_count++;
  263 }
  264 
  265 /**
  266  * This method will remove a dListFieldName from the head of the list.
  267  *
  268  * NOTE: This macro will always return a value, even if the list is empty.
  269  *       You must insure the list is not empty or use Dlist_safeRemoveHead.
  270  *
  271  * element - A pointer into which to save the address of the structure
  272  *           containing the SCI_FAST_LIST at the list head.
  273  */
  274 INLINE
  275 static void *sci_fast_list_remove_head(
  276     SCI_FAST_LIST_T *anchor
  277 )
  278 {
  279     void *object = NULL;
  280     SCI_FAST_LIST_ELEMENT_T *element;
  281     if ( anchor->list_head != NULL )
  282     {
  283         element = anchor->list_head;
  284         object = anchor->list_head->object;
  285         anchor->list_head = anchor->list_head->next;
  286         if ( anchor->list_head == NULL )
  287         {
  288             anchor->list_tail = NULL;
  289         }
  290         anchor->element_count--;
  291         element->next = element->prev = NULL;
  292         element->owning_list = NULL;
  293     }
  294     return object;
  295 }
  296 
  297 INLINE
  298 static void *sci_fast_list_remove_tail(
  299     SCI_FAST_LIST_T *anchor
  300 )
  301 {
  302     void *object = NULL;
  303     SCI_FAST_LIST_ELEMENT_T *element;
  304     if ( anchor->list_tail != NULL )
  305     {
  306         element = anchor->list_tail;
  307         object = element->object;
  308         anchor->list_tail = element->prev;
  309         if ( anchor->list_tail == NULL )
  310             anchor->list_head = NULL;
  311         anchor->element_count--;
  312         element->next = element->prev = NULL;
  313         element->owning_list = NULL;
  314     }
  315     return object;
  316 }
  317 
  318 /**
  319  * Remove an element from anywhere in the list referenced by name.
  320  */
  321 INLINE
  322 static void sci_fast_list_remove_element(
  323     SCI_FAST_LIST_ELEMENT_T *element
  324 )
  325 {
  326     if ( element->next == NULL )
  327         element->owning_list->list_tail = element->prev;
  328     else
  329         element->next->prev = element->prev;
  330 
  331     if ( element->prev == NULL )
  332         element->owning_list->list_head = element->next;
  333     else
  334         element->prev->next = element->next;
  335 
  336     element->owning_list->element_count--;
  337     element->next = element->prev = NULL;
  338     element->owning_list = NULL;
  339 }
  340 
  341 #endif // _SCI_FAST_LIST_HEADER_

Cache object: e48feb8ca2d6318c02df9885626d9575


[ 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.