MINOR: mt_list: Implement MT_LIST_POP_LOCKED()

Implement MT_LIST_POP_LOCKED(), that behaves as MT_LIST_POP() and
removes the first element from the list, if any, but keeps it locked.

This should be backported to 3.2, as it will be use in a bug fix in the
stick tables that affects 3.2 too.
This commit is contained in:
Olivier Houchard 2025-09-30 14:39:01 +02:00 committed by Olivier Houchard
parent 6316f958e3
commit cf26745857
2 changed files with 53 additions and 5 deletions

View File

@ -245,6 +245,30 @@ mt_list_pop(l)
#=========#
mt_list_pop_locked(l)
Removes the list's first element, returns it locked. If the list was empty,
NULL is returned. A macro MT_LIST_POP_LOCKED() is provided for a
more convenient use; instead of returning the list element, it will return
the structure holding the element, taking care of preserving the NULL.
before:
+---+ +---+ +---+ +---+ +---+ +---+ +---+
#=>| L |<===>| A |<===>| B |<===>| C |<===>| D |<===>| E |<===>| F |<=#
# +---+ +---+ +---+ +---+ +---+ +---+ +---+ #
#=====================================================================#
after:
+---+ +---+ +---+ +---+ +---+ +---+
#=>| L |<===>| B |<===>| C |<===>| D |<===>| E |<===>| F |<=#
# +---+ +---+ +---+ +---+ +---+ +---+ #
#===========================================================#
+---+
# x| A |x #
# +---+ #
#=========#
_mt_list_lock_next(elt)
Locks the link that starts at the next pointer of the designated element.
The link is replaced by two locked pointers, and a pointer to the next

View File

@ -128,6 +128,19 @@ struct mt_list {
(_n ? MT_LIST_ELEM(_n, t, m) : NULL); \
})
/* Returns a pointer of type <t> to the structure containing a member of type
* mt_list called <m> that comes from the first element in list <l>, that is
* atomically locked. If the list is empty, NULL is returned instead.
* Example:
*
* while ((conn = MT_LIST_POP_LOCKED(queue, struct conn *, list))) ...
*/
#define MT_LIST_POP_LOCKED(lh, t, m) \
({ \
struct mt_list *_n = mt_list_pop_locked(lh); \
(_n ? MT_LIST_ELEM(_n, t, m) : NULL); \
})
/* Iterates <item> through a list of items of type "typeof(*item)" which are
* linked via a "struct mt_list" member named <member>. A pointer to the head
* of the list is passed in <list_head>.
@ -633,10 +646,10 @@ static MT_INLINE long mt_list_delete(struct mt_list *el)
}
/* Removes the first element from the list <lh>, and returns it in detached
/* Removes the first element from the list <lh>, and returns it in locked
* form. If the list is already empty, NULL is returned instead.
*/
static MT_INLINE struct mt_list *mt_list_pop(struct mt_list *lh)
static MT_INLINE struct mt_list *mt_list_pop_locked(struct mt_list *lh)
{
struct mt_list *n, *n2;
struct mt_list *p, *p2;
@ -687,15 +700,26 @@ static MT_INLINE struct mt_list *mt_list_pop(struct mt_list *lh)
n2->prev = lh;
__atomic_thread_fence(__ATOMIC_RELEASE);
n->prev = n->next = n;
__atomic_thread_fence(__ATOMIC_RELEASE);
/* return n */
break;
}
return n;
}
/* Removes the first element from the list <lh>, and returns it in detached
* form. If the list is already empty, NULL is returned instead.
*/
static MT_INLINE struct mt_list *mt_list_pop(struct mt_list *lh)
{
struct mt_list *ret = mt_list_pop_locked(lh);
if (ret) {
ret->prev = ret->next = ret;
__atomic_thread_fence(__ATOMIC_RELEASE);
}
return ret;
}
/* Opens the list just after <lh> which usually is the list's head, but not
* necessarily. The link between <lh> and its next element is cut and replaced