mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-11-25 12:51:21 +01:00
MINOR: list: adding MT_LIST_APPEND_LOCKED macro
adding a new mt macro: MT_LIST_APPEND_LOCKED. This macro may be used to append an item to an existing list, like MT_LIST_APPEND. But here the item will be forced into locked/busy state prior to appending, so that it is already referenced in the list while still preventing concurrent accesses until we decide to unlock it. The macro returns a struct mt_list "np", that is needed at unlock time using regular MT_LIST_UNLOCK_ELT macro.
This commit is contained in:
parent
18c284c126
commit
e951c3435c
@ -416,6 +416,40 @@
|
|||||||
(_ret); \
|
(_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
|
||||||
|
* Item will be added in busy/locked state, so that it is already
|
||||||
|
* referenced in the list but no other thread can use it until we're ready.
|
||||||
|
*
|
||||||
|
* This returns a struct mt_list, that will be needed at unlock time.
|
||||||
|
* (using MT_LIST_UNLOCK_ELT)
|
||||||
|
*/
|
||||||
|
#define MT_LIST_APPEND_LOCKED(_lh, _el) \
|
||||||
|
({ \
|
||||||
|
struct mt_list np; \
|
||||||
|
struct mt_list *lh = (_lh), *el = (_el); \
|
||||||
|
(el)->next = MT_LIST_BUSY; \
|
||||||
|
(el)->prev = MT_LIST_BUSY; \
|
||||||
|
for (;;__ha_cpu_relax()) { \
|
||||||
|
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; \
|
||||||
|
} \
|
||||||
|
np.prev = p; \
|
||||||
|
np.next = n; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
(np); \
|
||||||
|
})
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Detach a list from its head. A pointer to the first element is returned
|
* 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
|
* and the list is closed. If the list was empty, NULL is returned. This may
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user