kernel: Add method to dequeue from a dlist

Dequeuing from a doubly linked list is similar to removing an item
except that it does not re-initialize the dequeued node.

This comes in handy when sorting a doubly linked list (where the
node gets removed and re-added). In that circumstance, re-initializing
the node is required. Furthermore, the compiler does not always
'understand' this. Thus, when performance is critical, dequeuing
may be preferred to removing.

Signed-off-by: Peter Mitsis <peter.mitsis@intel.com>
This commit is contained in:
Peter Mitsis 2024-10-25 11:17:26 -07:00 committed by Benjamin Cabé
parent d1c2fc0667
commit 472c71d3f4
2 changed files with 25 additions and 2 deletions

View file

@ -492,6 +492,29 @@ static inline void sys_dlist_insert_at(sys_dlist_t *list, sys_dnode_t *node,
}
}
/**
* @brief remove a specific node from a list
*
* Like :c:func:`sys_dlist_remove()`, this routine removes a specific node
* from a list. However, unlike :c:func:`sys_dlist_remove()`, this routine
* does not re-initialize the removed node. One significant implication of
* this difference is that the function :c:func`sys_dnode_is_linked()` will
* not work on a dequeued node.
*
* The list is implicit from the node. The node must be part of a list.
* This and other sys_dlist_*() functions are not thread safe.
*
* @param node the node to dequeue
*/
static inline void sys_dlist_dequeue(sys_dnode_t *node)
{
sys_dnode_t *const prev = node->prev;
sys_dnode_t *const next = node->next;
prev->next = next;
next->prev = prev;
}
/**
* @brief remove a specific node from a list
*

View file

@ -241,8 +241,8 @@ static ALWAYS_INLINE void z_priq_mq_remove(struct _priq_mq *pq,
{
struct prio_info pos = get_prio_info(thread->base.prio);
sys_dlist_remove(&thread->base.qnode_dlist);
if (sys_dlist_is_empty(&pq->queues[pos.offset_prio])) {
sys_dlist_dequeue(&thread->base.qnode_dlist);
if (unlikely(sys_dlist_is_empty(&pq->queues[pos.offset_prio]))) {
pq->bitmask[pos.idx] &= ~BIT(pos.bit);
}
}