| .. | .. |
|---|
| 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)); |
|---|