diff --git a/include/haproxy/list.h b/include/haproxy/list.h index 2f2699f17..98d9f6962 100644 --- a/include/haproxy/list.h +++ b/include/haproxy/list.h @@ -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 through a list of items of type "typeof(*item)" which are * linked via a "struct list" member named . A pointer to the head of