LCOV - code coverage report
Current view: top level - include - list.h (source / functions) Hit Total Coverage
Test: coverage3.info Lines: 28 30 93.3 %
Date: 2014-04-22 Functions: 0 0 -
Branches: 5 8 62.5 %

           Branch data     Line data    Source code
       1                 :            : #ifndef __CR_LIST_H__
       2                 :            : #define __CR_LIST_H__
       3                 :            : 
       4                 :            : /*
       5                 :            :  * Double linked lists.
       6                 :            :  */
       7                 :            : 
       8                 :            : #include "compiler.h"
       9                 :            : 
      10                 :            : #define POISON_POINTER_DELTA 0
      11                 :            : #define LIST_POISON1  ((void *) 0x00100100 + POISON_POINTER_DELTA)
      12                 :            : #define LIST_POISON2  ((void *) 0x00200200 + POISON_POINTER_DELTA)
      13                 :            : 
      14                 :            : struct list_head {
      15                 :            :         struct list_head *prev, *next;
      16                 :            : };
      17                 :            : 
      18                 :            : #define LIST_HEAD_INIT(name)    { &(name), &(name) }
      19                 :            : #define LIST_HEAD(name)         struct list_head name = LIST_HEAD_INIT(name)
      20                 :            : 
      21                 :            : static inline void INIT_LIST_HEAD(struct list_head *list)
      22                 :            : {
      23                 :     906365 :         list->next = list;
      24                 :     140577 :         list->prev = list;
      25                 :            : }
      26                 :            : 
      27                 :            : static inline void __list_add(struct list_head *new,
      28                 :            :                               struct list_head *prev,
      29                 :            :                               struct list_head *next)
      30                 :            : {
      31                 :     393567 :         next->prev   = new;
      32                 :     393567 :         new->next    = next;
      33                 :     393567 :         new->prev    = prev;
      34                 :     138349 :         prev->next   = new;
      35                 :            : }
      36                 :            : 
      37                 :            : static inline void list_add(struct list_head *new, struct list_head *head)
      38                 :            : {
      39                 :      73934 :         __list_add(new, head, head->next);
      40                 :            : }
      41                 :            : 
      42                 :            : static inline void list_add_tail(struct list_head *new, struct list_head *head)
      43                 :            : {
      44                 :     319617 :         __list_add(new, head->prev, head);
      45                 :            : }
      46                 :            : 
      47                 :            : static inline void __list_del(struct list_head * prev, struct list_head * next)
      48                 :            : {
      49                 :      77011 :         next->prev = prev;
      50                 :      77011 :         prev->next = next;
      51                 :            : }
      52                 :            : 
      53                 :            : static inline void __list_del_entry(struct list_head *entry)
      54                 :            : {
      55                 :        546 :         __list_del(entry->prev, entry->next);
      56                 :            : }
      57                 :            : 
      58                 :            : static inline void list_del(struct list_head *entry)
      59                 :            : {
      60                 :      76465 :         __list_del(entry->prev, entry->next);
      61                 :      76465 :         entry->next = LIST_POISON1;
      62                 :      76465 :         entry->prev = LIST_POISON2;
      63                 :            : }
      64                 :            : 
      65                 :            : static inline void list_replace(struct list_head *old,
      66                 :            :                                 struct list_head *new)
      67                 :            : {
      68                 :            :         new->next            = old->next;
      69                 :            :         new->next->prev           = new;
      70                 :            :         new->prev            = old->prev;
      71                 :            :         new->prev->next           = new;
      72                 :            : }
      73                 :            : 
      74                 :            : static inline void list_replace_init(struct list_head *old,
      75                 :            :                                         struct list_head *new)
      76                 :            : {
      77                 :            :         list_replace(old, new);
      78                 :            :         INIT_LIST_HEAD(old);
      79                 :            : }
      80                 :            : 
      81                 :            : static inline void list_del_init(struct list_head *entry)
      82                 :            : {
      83                 :            :         __list_del_entry(entry);
      84                 :            :         INIT_LIST_HEAD(entry);
      85                 :            : }
      86                 :            : 
      87                 :            : static inline void list_move(struct list_head *list, struct list_head *head)
      88                 :            : {
      89                 :            :         __list_del_entry(list);
      90                 :            :         list_add(list, head);
      91                 :            : }
      92                 :            : 
      93                 :            : static inline void list_move_tail(struct list_head *list,
      94                 :            :                                   struct list_head *head)
      95                 :            : {
      96                 :            :         __list_del_entry(list);
      97                 :            :         list_add_tail(list, head);
      98                 :            : }
      99                 :            : 
     100                 :            : static inline int list_is_last(const struct list_head *list,
     101                 :            :                                 const struct list_head *head)
     102                 :            : {
     103                 :            :         return list->next == head;
     104                 :            : }
     105                 :            : 
     106                 :            : static inline int list_is_first(const struct list_head *list,
     107                 :            :                                 const struct list_head *head)
     108                 :            : {
     109                 :            :         return list->prev == head;
     110                 :            : }
     111                 :            : 
     112                 :            : static inline int list_empty(const struct list_head *head)
     113                 :            : {
     114                 :    1065154 :         return head->next == head;
     115                 :            : }
     116                 :            : 
     117                 :            : static inline int list_empty_careful(const struct list_head *head)
     118                 :            : {
     119                 :            :         struct list_head *next = head->next;
     120                 :            :         return (next == head) && (next == head->prev);
     121                 :            : }
     122                 :            : static inline void list_rotate_left(struct list_head *head)
     123                 :            : {
     124                 :            :         struct list_head *first;
     125                 :            : 
     126                 :            :         if (!list_empty(head)) {
     127                 :            :                 first = head->next;
     128                 :            :                 list_move_tail(first, head);
     129                 :            :         }
     130                 :            : }
     131                 :            : 
     132                 :            : static inline int list_is_singular(const struct list_head *head)
     133                 :            : {
     134                 :            :         return !list_empty(head) && (head->next == head->prev);
     135                 :            : }
     136                 :            : 
     137                 :            : static inline void __list_cut_position(struct list_head *list,
     138                 :            :                 struct list_head *head, struct list_head *entry)
     139                 :            : {
     140                 :            :         struct list_head *new_first = entry->next;
     141                 :            :         list->next = head->next;
     142                 :            :         list->next->prev = list;
     143                 :            :         list->prev = entry;
     144                 :            :         entry->next = list;
     145                 :            :         head->next = new_first;
     146                 :            :         new_first->prev = head;
     147                 :            : }
     148                 :            : 
     149                 :            : static inline void list_cut_position(struct list_head *list,
     150                 :            :                 struct list_head *head, struct list_head *entry)
     151                 :            : {
     152                 :            :         if (list_empty(head))
     153                 :            :                 return;
     154                 :            :         if (list_is_singular(head) &&
     155                 :            :                 (head->next != entry && head != entry))
     156                 :            :                 return;
     157                 :            :         if (entry == head)
     158                 :            :                 INIT_LIST_HEAD(list);
     159                 :            :         else
     160                 :            :                 __list_cut_position(list, head, entry);
     161                 :            : }
     162                 :            : 
     163                 :            : static inline void __list_splice(const struct list_head *list,
     164                 :            :                                  struct list_head *prev,
     165                 :            :                                  struct list_head *next)
     166                 :            : {
     167                 :            :         struct list_head *first = list->next;
     168                 :      16784 :         struct list_head *last = list->prev;
     169                 :            : 
     170                 :      16784 :         first->prev  = prev;
     171                 :      16784 :         prev->next   = first;
     172                 :            : 
     173                 :      16784 :         last->next   = next;
     174                 :      16784 :         next->prev   = last;
     175                 :            : }
     176                 :            : 
     177                 :            : static inline void list_splice(const struct list_head *list,
     178                 :            :                                 struct list_head *head)
     179                 :            : {
     180 [ -  + ][ +  + ]:      78086 :         if (!list_empty(list))
     181                 :          8 :                 __list_splice(list, head, head->next);
     182                 :            : }
     183                 :            : 
     184                 :            : static inline void list_splice_tail(struct list_head *list,
     185                 :            :                                 struct list_head *head)
     186                 :            : {
     187                 :            :         if (!list_empty(list))
     188                 :            :                 __list_splice(list, head->prev, head);
     189                 :            : }
     190                 :            : 
     191                 :            : static inline void list_splice_init(struct list_head *list,
     192                 :            :                                     struct list_head *head)
     193                 :            : {
     194         [ #  # ]:          0 :         if (!list_empty(list)) {
     195                 :          0 :                 __list_splice(list, head, head->next);
     196                 :            :                 INIT_LIST_HEAD(list);
     197                 :            :         }
     198                 :            : }
     199                 :            : 
     200                 :            : static inline void list_splice_tail_init(struct list_head *list,
     201                 :            :                                          struct list_head *head)
     202                 :            : {
     203                 :            :         if (!list_empty(list)) {
     204                 :            :                 __list_splice(list, head->prev, head);
     205                 :            :                 INIT_LIST_HEAD(list);
     206                 :            :         }
     207                 :            : }
     208                 :            : 
     209                 :            : #define list_entry(ptr, type, member)                           \
     210                 :            :         container_of(ptr, type, member)
     211                 :            : 
     212                 :            : #define list_first_entry(ptr, type, member)                     \
     213                 :            :         list_entry((ptr)->next, type, member)
     214                 :            : 
     215                 :            : #define list_for_each(pos, head)                                \
     216                 :            :         for (pos = (head)->next; pos != (head); pos = pos->next)
     217                 :            : 
     218                 :            : #define __list_for_each(pos, head)                              \
     219                 :            :         for (pos = (head)->next; pos != (head); pos = pos->next)
     220                 :            : 
     221                 :            : #define list_for_each_prev(pos, head)                           \
     222                 :            :         for (pos = (head)->prev; pos != (head); pos = pos->prev)
     223                 :            : 
     224                 :            : #define list_for_each_safe(pos, n, head)                        \
     225                 :            :         for (pos = (head)->next, n = pos->next; pos != (head);    \
     226                 :            :                 pos = n, n = pos->next)
     227                 :            : 
     228                 :            : #define list_for_each_prev_safe(pos, n, head)                   \
     229                 :            :         for (pos = (head)->prev, n = pos->prev;                   \
     230                 :            :              pos != (head);                                     \
     231                 :            :              pos = n, n = pos->prev)
     232                 :            : 
     233                 :            : #define list_for_each_entry(pos, head, member)                          \
     234                 :            :         for (pos = list_entry((head)->next, typeof(*pos), member);   \
     235                 :            :              &pos->member != (head);                                     \
     236                 :            :              pos = list_entry(pos->member.next, typeof(*pos), member))
     237                 :            : 
     238                 :            : #define list_for_each_entry_reverse(pos, head, member)                  \
     239                 :            :         for (pos = list_entry((head)->prev, typeof(*pos), member);   \
     240                 :            :              &pos->member != (head);                                     \
     241                 :            :              pos = list_entry(pos->member.prev, typeof(*pos), member))
     242                 :            : 
     243                 :            : #define list_prepare_entry(pos, head, member)                           \
     244                 :            :         ((pos) ? : list_entry(head, typeof(*pos), member))
     245                 :            : 
     246                 :            : #define list_for_each_entry_continue(pos, head, member)                 \
     247                 :            :         for (pos = list_entry(pos->member.next, typeof(*pos), member);       \
     248                 :            :              &pos->member != (head);                                     \
     249                 :            :              pos = list_entry(pos->member.next, typeof(*pos), member))
     250                 :            : 
     251                 :            : #define list_for_each_entry_continue_reverse(pos, head, member)         \
     252                 :            :         for (pos = list_entry(pos->member.prev, typeof(*pos), member);       \
     253                 :            :              &pos->member != (head);                                     \
     254                 :            :              pos = list_entry(pos->member.prev, typeof(*pos), member))
     255                 :            : 
     256                 :            : #define list_for_each_entry_from(pos, head, member)                     \
     257                 :            :         for (; &pos->member != (head);                                   \
     258                 :            :              pos = list_entry(pos->member.next, typeof(*pos), member))
     259                 :            : 
     260                 :            : #define list_for_each_entry_safe(pos, n, head, member)                  \
     261                 :            :         for (pos = list_entry((head)->next, typeof(*pos), member),   \
     262                 :            :                 n = list_entry(pos->member.next, typeof(*pos), member);      \
     263                 :            :              &pos->member != (head);                                     \
     264                 :            :              pos = n, n = list_entry(n->member.next, typeof(*n), member))
     265                 :            : 
     266                 :            : #define list_for_each_entry_safe_continue(pos, n, head, member)                 \
     267                 :            :         for (pos = list_entry(pos->member.next, typeof(*pos), member),               \
     268                 :            :                 n = list_entry(pos->member.next, typeof(*pos), member);              \
     269                 :            :              &pos->member != (head);                                             \
     270                 :            :              pos = n, n = list_entry(n->member.next, typeof(*n), member))
     271                 :            : 
     272                 :            : #define list_for_each_entry_safe_from(pos, n, head, member)                     \
     273                 :            :         for (n = list_entry(pos->member.next, typeof(*pos), member);         \
     274                 :            :              &pos->member != (head);                                             \
     275                 :            :              pos = n, n = list_entry(n->member.next, typeof(*n), member))
     276                 :            : 
     277                 :            : #define list_for_each_entry_safe_reverse(pos, n, head, member)          \
     278                 :            :         for (pos = list_entry((head)->prev, typeof(*pos), member),   \
     279                 :            :                 n = list_entry(pos->member.prev, typeof(*pos), member);      \
     280                 :            :              &pos->member != (head);                                     \
     281                 :            :              pos = n, n = list_entry(n->member.prev, typeof(*n), member))
     282                 :            : 
     283                 :            : #define list_safe_reset_next(pos, n, member)                            \
     284                 :            :         n = list_entry(pos->member.next, typeof(*pos), member)
     285                 :            : 
     286                 :            : /*
     287                 :            :  * Double linked lists with a single pointer list head.
     288                 :            :  */
     289                 :            : 
     290                 :            : struct hlist_head {
     291                 :            :         struct hlist_node *first;
     292                 :            : };
     293                 :            : 
     294                 :            : struct hlist_node {
     295                 :            :         struct hlist_node *next, **pprev;
     296                 :            : };
     297                 :            : 
     298                 :            : #define HLIST_HEAD_INIT         { .first = NULL }
     299                 :            : #define HLIST_HEAD(name)        struct hlist_head name = {  .first = NULL }
     300                 :            : #define INIT_HLIST_HEAD(ptr)    ((ptr)->first = NULL)
     301                 :            : 
     302                 :            : static inline void INIT_HLIST_NODE(struct hlist_node *h)
     303                 :            : {
     304                 :            :         h->next = NULL;
     305                 :            :         h->pprev = NULL;
     306                 :            : }
     307                 :            : 
     308                 :            : static inline int hlist_unhashed(const struct hlist_node *h)
     309                 :            : {
     310                 :            :         return !h->pprev;
     311                 :            : }
     312                 :            : 
     313                 :            : static inline int hlist_empty(const struct hlist_head *h)
     314                 :            : {
     315                 :            :         return !h->first;
     316                 :            : }
     317                 :            : 
     318                 :            : static inline void __hlist_del(struct hlist_node *n)
     319                 :            : {
     320                 :            :         struct hlist_node *next = n->next;
     321                 :            :         struct hlist_node **pprev = n->pprev;
     322                 :            :         *pprev = next;
     323                 :            :         if (next)
     324                 :            :                 next->pprev = pprev;
     325                 :            : }
     326                 :            : 
     327                 :            : static inline void hlist_del(struct hlist_node *n)
     328                 :            : {
     329                 :            :         __hlist_del(n);
     330                 :            :         n->next = LIST_POISON1;
     331                 :            :         n->pprev = LIST_POISON2;
     332                 :            : }
     333                 :            : 
     334                 :            : static inline void hlist_del_init(struct hlist_node *n)
     335                 :            : {
     336                 :            :         if (!hlist_unhashed(n)) {
     337                 :            :                 __hlist_del(n);
     338                 :            :                 INIT_HLIST_NODE(n);
     339                 :            :         }
     340                 :            : }
     341                 :            : 
     342                 :            : static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
     343                 :            : {
     344                 :       3733 :         struct hlist_node *first = h->first;
     345                 :       3733 :         n->next = first;
     346         [ +  + ]:       3733 :         if (first)
     347                 :         24 :                 first->pprev = &n->next;
     348                 :       3733 :         h->first = n;
     349                 :       3733 :         n->pprev = &h->first;
     350                 :            : }
     351                 :            : 
     352                 :            : /* next must be != NULL */
     353                 :            : static inline void hlist_add_before(struct hlist_node *n,
     354                 :            :                                     struct hlist_node *next)
     355                 :            : {
     356                 :            :         n->pprev = next->pprev;
     357                 :            :         n->next = next;
     358                 :            :         next->pprev = &n->next;
     359                 :            :         *(n->pprev) = n;
     360                 :            : }
     361                 :            : 
     362                 :            : static inline void hlist_add_after(struct hlist_node *n,
     363                 :            :                                    struct hlist_node *next)
     364                 :            : {
     365                 :            :         next->next = n->next;
     366                 :            :         n->next = next;
     367                 :            :         next->pprev = &n->next;
     368                 :            : 
     369                 :            :         if (next->next)
     370                 :            :                 next->next->pprev  = &next->next;
     371                 :            : }
     372                 :            : 
     373                 :            : /* after that we'll appear to be on some hlist and hlist_del will work */
     374                 :            : static inline void hlist_add_fake(struct hlist_node *n)
     375                 :            : {
     376                 :            :         n->pprev = &n->next;
     377                 :            : }
     378                 :            : 
     379                 :            : /*
     380                 :            :  * Move a list from one list head to another. Fixup the pprev
     381                 :            :  * reference of the first entry if it exists.
     382                 :            :  */
     383                 :            : static inline void hlist_move_list(struct hlist_head *old,
     384                 :            :                                    struct hlist_head *new)
     385                 :            : {
     386                 :            :         new->first = old->first;
     387                 :            :         if (new->first)
     388                 :            :                 new->first->pprev = &new->first;
     389                 :            :         old->first = NULL;
     390                 :            : }
     391                 :            : 
     392                 :            : #define hlist_entry(ptr, type, member) container_of(ptr,type,member)
     393                 :            : 
     394                 :            : #define hlist_for_each(pos, head)                                               \
     395                 :            :         for (pos = (head)->first; pos ; pos = pos->next)
     396                 :            : 
     397                 :            : #define hlist_for_each_safe(pos, n, head)                                       \
     398                 :            :         for (pos = (head)->first; pos && ({ n = pos->next; 1; });         \
     399                 :            :              pos = n)
     400                 :            : 
     401                 :            : #define hlist_entry_safe(ptr, type, member)                                     \
     402                 :            :         (ptr) ? hlist_entry(ptr, type, member) : NULL
     403                 :            : 
     404                 :            : #define hlist_for_each_entry(pos, head, member)                                 \
     405                 :            :         for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);  \
     406                 :            :              pos;                                                               \
     407                 :            :              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
     408                 :            : 
     409                 :            : #define hlist_for_each_entry_continue(pos, member)                              \
     410                 :            :         for (pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member);\
     411                 :            :              pos;                                                               \
     412                 :            :              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
     413                 :            : 
     414                 :            : #define hlist_for_each_entry_from(pos, member)                                  \
     415                 :            :         for (; pos;                                                             \
     416                 :            :              pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
     417                 :            : 
     418                 :            : #define hlist_for_each_entry_safe(pos, n, head, member)                         \
     419                 :            :         for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);    \
     420                 :            :              pos && ({ n = pos->member.next; 1; });                          \
     421                 :            :              pos = hlist_entry_safe(n, typeof(*pos), member))
     422                 :            : 
     423                 :            : #endif /* __CR_LIST_H__ */

Generated by: LCOV version 1.9