.. | .. |
---|
56 | 56 | return ((unsigned long)ptr) >> 1; |
---|
57 | 57 | } |
---|
58 | 58 | |
---|
| 59 | +/** |
---|
| 60 | + * hlist_nulls_unhashed - Has node been removed and reinitialized? |
---|
| 61 | + * @h: Node to be checked |
---|
| 62 | + * |
---|
| 63 | + * Not that not all removal functions will leave a node in unhashed state. |
---|
| 64 | + * For example, hlist_del_init_rcu() leaves the node in unhashed state, |
---|
| 65 | + * but hlist_nulls_del() does not. |
---|
| 66 | + */ |
---|
59 | 67 | static inline int hlist_nulls_unhashed(const struct hlist_nulls_node *h) |
---|
60 | 68 | { |
---|
61 | 69 | return !h->pprev; |
---|
62 | 70 | } |
---|
63 | 71 | |
---|
| 72 | +/** |
---|
| 73 | + * hlist_nulls_unhashed_lockless - Has node been removed and reinitialized? |
---|
| 74 | + * @h: Node to be checked |
---|
| 75 | + * |
---|
| 76 | + * Not that not all removal functions will leave a node in unhashed state. |
---|
| 77 | + * For example, hlist_del_init_rcu() leaves the node in unhashed state, |
---|
| 78 | + * but hlist_nulls_del() does not. Unlike hlist_nulls_unhashed(), this |
---|
| 79 | + * function may be used locklessly. |
---|
| 80 | + */ |
---|
| 81 | +static inline int hlist_nulls_unhashed_lockless(const struct hlist_nulls_node *h) |
---|
| 82 | +{ |
---|
| 83 | + return !READ_ONCE(h->pprev); |
---|
| 84 | +} |
---|
| 85 | + |
---|
64 | 86 | static inline int hlist_nulls_empty(const struct hlist_nulls_head *h) |
---|
65 | 87 | { |
---|
66 | 88 | return is_a_nulls(READ_ONCE(h->first)); |
---|