From: Olivier Houchard Date: Mon, 29 Jun 2020 18:14:28 +0000 (+0200) Subject: MINOR: list: Add MT_LIST_DEL_SAFE_NOINIT() and MT_LIST_ADDQ_NOCHECK() X-Git-Tag: v2.2-dev12~25 X-Git-Url: http://git.haproxy.org/?a=commitdiff_plain;h=bbee1f7e78a5abe5676acb6c33f71e1f3f651119;p=haproxy-2.3.git 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. --- diff --git a/include/haproxy/list.h b/include/haproxy/list.h index 2f2699f..98d9f69 100644 --- a/include/haproxy/list.h +++ b/include/haproxy/list.h @@ -299,6 +299,39 @@ }) /* + * 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 * exclusively be used with lists modified by MT_LIST_ADD/MT_LIST_ADDQ. This @@ -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