LCOV - code coverage report
Current view: top level - include/linux - list_nulls.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 7 15 46.7 %
Date: 2014-04-07 Functions: 0 0 -
Branches: 5 10 50.0 %

           Branch data     Line data    Source code
       1                 :            : #ifndef _LINUX_LIST_NULLS_H
       2                 :            : #define _LINUX_LIST_NULLS_H
       3                 :            : 
       4                 :            : /*
       5                 :            :  * Special version of lists, where end of list is not a NULL pointer,
       6                 :            :  * but a 'nulls' marker, which can have many different values.
       7                 :            :  * (up to 2^31 different values guaranteed on all platforms)
       8                 :            :  *
       9                 :            :  * In the standard hlist, termination of a list is the NULL pointer.
      10                 :            :  * In this special 'nulls' variant, we use the fact that objects stored in
      11                 :            :  * a list are aligned on a word (4 or 8 bytes alignment).
      12                 :            :  * We therefore use the last significant bit of 'ptr' :
      13                 :            :  * Set to 1 : This is a 'nulls' end-of-list marker (ptr >> 1)
      14                 :            :  * Set to 0 : This is a pointer to some object (ptr)
      15                 :            :  */
      16                 :            : 
      17                 :            : struct hlist_nulls_head {
      18                 :            :         struct hlist_nulls_node *first;
      19                 :            : };
      20                 :            : 
      21                 :            : struct hlist_nulls_node {
      22                 :            :         struct hlist_nulls_node *next, **pprev;
      23                 :            : };
      24                 :            : #define INIT_HLIST_NULLS_HEAD(ptr, nulls) \
      25                 :            :         ((ptr)->first = (struct hlist_nulls_node *) (1UL | (((long)nulls) << 1)))
      26                 :            : 
      27                 :            : #define hlist_nulls_entry(ptr, type, member) container_of(ptr,type,member)
      28                 :            : /**
      29                 :            :  * ptr_is_a_nulls - Test if a ptr is a nulls
      30                 :            :  * @ptr: ptr to be tested
      31                 :            :  *
      32                 :            :  */
      33                 :            : static inline int is_a_nulls(const struct hlist_nulls_node *ptr)
      34                 :            : {
      35                 :     125258 :         return ((unsigned long)ptr & 1);
      36                 :            : }
      37                 :            : 
      38                 :            : /**
      39                 :            :  * get_nulls_value - Get the 'nulls' value of the end of chain
      40                 :            :  * @ptr: end of chain
      41                 :            :  *
      42                 :            :  * Should be called only if is_a_nulls(ptr);
      43                 :            :  */
      44                 :            : static inline unsigned long get_nulls_value(const struct hlist_nulls_node *ptr)
      45                 :            : {
      46                 :      17194 :         return ((unsigned long)ptr) >> 1;
      47                 :            : }
      48                 :            : 
      49                 :            : static inline int hlist_nulls_unhashed(const struct hlist_nulls_node *h)
      50                 :            : {
      51                 :            :         return !h->pprev;
      52                 :            : }
      53                 :            : 
      54                 :            : static inline int hlist_nulls_empty(const struct hlist_nulls_head *h)
      55                 :            : {
      56                 :      47288 :         return is_a_nulls(h->first);
      57                 :            : }
      58                 :            : 
      59                 :            : static inline void hlist_nulls_add_head(struct hlist_nulls_node *n,
      60                 :            :                                         struct hlist_nulls_head *h)
      61                 :            : {
      62                 :          0 :         struct hlist_nulls_node *first = h->first;
      63                 :            : 
      64                 :          0 :         n->next = first;
      65                 :          0 :         n->pprev = &h->first;
      66                 :          0 :         h->first = n;
      67         [ #  # ]:          0 :         if (!is_a_nulls(first))
      68                 :          0 :                 first->pprev = &n->next;
      69                 :            : }
      70                 :            : 
      71                 :            : static inline void __hlist_nulls_del(struct hlist_nulls_node *n)
      72                 :            : {
      73                 :        262 :         struct hlist_nulls_node *next = n->next;
      74                 :          0 :         struct hlist_nulls_node **pprev = n->pprev;
      75                 :        262 :         *pprev = next;
      76 [ +  + ][ #  # ]:        262 :         if (!is_a_nulls(next))
         [ -  + ][ +  + ]
      77                 :          3 :                 next->pprev = pprev;
      78                 :            : }
      79                 :            : 
      80                 :            : static inline void hlist_nulls_del(struct hlist_nulls_node *n)
      81                 :            : {
      82                 :            :         __hlist_nulls_del(n);
      83                 :          0 :         n->pprev = LIST_POISON2;
      84                 :            : }
      85                 :            : 
      86                 :            : /**
      87                 :            :  * hlist_nulls_for_each_entry   - iterate over list of given type
      88                 :            :  * @tpos:       the type * to use as a loop cursor.
      89                 :            :  * @pos:        the &struct hlist_node to use as a loop cursor.
      90                 :            :  * @head:       the head for your list.
      91                 :            :  * @member:     the name of the hlist_node within the struct.
      92                 :            :  *
      93                 :            :  */
      94                 :            : #define hlist_nulls_for_each_entry(tpos, pos, head, member)                    \
      95                 :            :         for (pos = (head)->first;                                           \
      96                 :            :              (!is_a_nulls(pos)) &&                                             \
      97                 :            :                 ({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1;}); \
      98                 :            :              pos = pos->next)
      99                 :            : 
     100                 :            : /**
     101                 :            :  * hlist_nulls_for_each_entry_from - iterate over a hlist continuing from current point
     102                 :            :  * @tpos:       the type * to use as a loop cursor.
     103                 :            :  * @pos:        the &struct hlist_node to use as a loop cursor.
     104                 :            :  * @member:     the name of the hlist_node within the struct.
     105                 :            :  *
     106                 :            :  */
     107                 :            : #define hlist_nulls_for_each_entry_from(tpos, pos, member)      \
     108                 :            :         for (; (!is_a_nulls(pos)) &&                            \
     109                 :            :                 ({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1;}); \
     110                 :            :              pos = pos->next)
     111                 :            : 
     112                 :            : #endif

Generated by: LCOV version 1.9