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/lib/llist.c

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  * Lock-less NULL terminated single linked list
    3  *
    4  * The basic atomic operation of this list is cmpxchg on long.  On
    5  * architectures that don't have NMI-safe cmpxchg implementation, the
    6  * list can NOT be used in NMI handlers.  So code that uses the list in
    7  * an NMI handler should depend on CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG.
    8  *
    9  * Copyright 2010,2011 Intel Corp.
   10  *   Author: Huang Ying <ying.huang@intel.com>
   11  *
   12  * This program is free software; you can redistribute it and/or
   13  * modify it under the terms of the GNU General Public License version
   14  * 2 as published by the Free Software Foundation;
   15  *
   16  * This program is distributed in the hope that it will be useful,
   17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   19  * GNU General Public License for more details.
   20  *
   21  * You should have received a copy of the GNU General Public License
   22  * along with this program; if not, write to the Free Software
   23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   24  */
   25 #include <linux/kernel.h>
   26 #include <linux/export.h>
   27 #include <linux/interrupt.h>
   28 #include <linux/llist.h>
   29 
   30 
   31 /**
   32  * llist_add_batch - add several linked entries in batch
   33  * @new_first:  first entry in batch to be added
   34  * @new_last:   last entry in batch to be added
   35  * @head:       the head for your lock-less list
   36  *
   37  * Return whether list is empty before adding.
   38  */
   39 bool llist_add_batch(struct llist_node *new_first, struct llist_node *new_last,
   40                      struct llist_head *head)
   41 {
   42         struct llist_node *entry, *old_entry;
   43 
   44         entry = head->first;
   45         for (;;) {
   46                 old_entry = entry;
   47                 new_last->next = entry;
   48                 entry = cmpxchg(&head->first, old_entry, new_first);
   49                 if (entry == old_entry)
   50                         break;
   51         }
   52 
   53         return old_entry == NULL;
   54 }
   55 EXPORT_SYMBOL_GPL(llist_add_batch);
   56 
   57 /**
   58  * llist_del_first - delete the first entry of lock-less list
   59  * @head:       the head for your lock-less list
   60  *
   61  * If list is empty, return NULL, otherwise, return the first entry
   62  * deleted, this is the newest added one.
   63  *
   64  * Only one llist_del_first user can be used simultaneously with
   65  * multiple llist_add users without lock.  Because otherwise
   66  * llist_del_first, llist_add, llist_add (or llist_del_all, llist_add,
   67  * llist_add) sequence in another user may change @head->first->next,
   68  * but keep @head->first.  If multiple consumers are needed, please
   69  * use llist_del_all or use lock between consumers.
   70  */
   71 struct llist_node *llist_del_first(struct llist_head *head)
   72 {
   73         struct llist_node *entry, *old_entry, *next;
   74 
   75         entry = head->first;
   76         for (;;) {
   77                 if (entry == NULL)
   78                         return NULL;
   79                 old_entry = entry;
   80                 next = entry->next;
   81                 entry = cmpxchg(&head->first, old_entry, next);
   82                 if (entry == old_entry)
   83                         break;
   84         }
   85 
   86         return entry;
   87 }
   88 EXPORT_SYMBOL_GPL(llist_del_first);

Cache object: 36ba0f1a608653adc8a5bfc0a25b2242


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