MINOR: list: Add MT_LIST_DEL_SAFE_NOINIT() and MT_LIST_ADDQ_NOCHECK()

Add two new macros, MT_LIST_DEL_SAFE_NOINIT makes sure we remove the
element from the list, without reinitializing its next and prev, and
MT_LIST_ADDQ_NOCHECK is similar to MT_LIST_ADDQ(), except it doesn't check
if the element is already in a list.
The goal is to be able to move an element from a list we're currently
parsing to another, keeping it locked in the meanwhile.
This commit is contained in:
Olivier Houchard 2020-06-29 20:14:28 +02:00 committed by Willy Tarreau
parent 88d18f81ae
commit bbee1f7e78

View file

@ -298,6 +298,39 @@
(_ret); \
})
/*
* Add an item at the end of a list.
* It is assumed the element can't already be in a list, so it isn't checked
*/
#define MT_LIST_ADDQ_NOCHECK(_lh, _el) \
({ \
int _ret = 0; \
struct mt_list *lh = (_lh), *el = (_el); \
while (1) { \
struct mt_list *n; \
struct mt_list *p; \
p = _HA_ATOMIC_XCHG(&(lh)->prev, MT_LIST_BUSY); \
if (p == MT_LIST_BUSY) \
continue; \
n = _HA_ATOMIC_XCHG(&p->next, MT_LIST_BUSY); \
if (n == MT_LIST_BUSY) { \
(lh)->prev = p; \
__ha_barrier_store(); \
continue; \
} \
(el)->next = n; \
(el)->prev = p; \
__ha_barrier_store(); \
p->next = (el); \
__ha_barrier_store(); \
n->prev = (el); \
__ha_barrier_store(); \
_ret = 1; \
break; \
} \
(_ret); \
})
/*
* Detach a list from its head. A pointer to the first element is returned
* and the list is closed. If the list was empty, NULL is returned. This may
@ -624,6 +657,12 @@
(_el) = NULL; \
} while (0)
/* Safe as MT_LIST_DEL_SAFE, but it won't reinit the element */
#define MT_LIST_DEL_SAFE_NOINIT(_el) \
do { \
(_el) = NULL; \
} while (0)
/* Simpler FOREACH_ITEM_SAFE macro inspired from Linux sources.
* Iterates <item> through a list of items of type "typeof(*item)" which are
* linked via a "struct list" member named <member>. A pointer to the head of