blob: 2c9be2ead14612ef2dc2627ce3ce0e8ddf0cd717 [file]
/* wait queue for multiple threads on kernel objects */
/*
* Copyright (c) 2015 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_KERNEL_INCLUDE_WAIT_Q_H_
#define ZEPHYR_KERNEL_INCLUDE_WAIT_Q_H_
#include <zephyr/kernel_structs.h>
#include <zephyr/sys/dlist.h>
#include <zephyr/sys/rb.h>
#include <timeout_q.h>
#include <priority_q.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef CONFIG_WAITQ_SCALABLE
/**
* Walk all threads pending on a wait queue.
*
* @param wq Wait queue
* @param thread_ptr Thread pointer iterator variable
*
* @warning Do not remove thread from wait queue when using this macro.
*/
#define _WAIT_Q_FOR_EACH(wq, thread_ptr) \
RB_FOR_EACH_CONTAINER(&(wq)->waitq.tree, thread_ptr, base.qnode_rb)
/*
* RB_FOR_EACH_SAFE() does not (and cannot) exist so we are not
* able to provide _WAIT_Q_FOR_EACH_SAFE when CONFIG_WAITQ_SCALABLE=y.
*/
static inline void z_waitq_init(_wait_q_t *w)
{
w->waitq = (struct _priq_rb) {
.tree = {
.lessthan_fn = z_priq_rb_lessthan
}
};
}
static inline struct k_thread *z_waitq_head(_wait_q_t *w)
{
return (struct k_thread *)rb_get_min(&w->waitq.tree);
}
#else /* !CONFIG_WAITQ_SCALABLE: */
/**
* Walk all threads pending on a wait queue.
*
* @param wq Wait queue
* @param thread_ptr Thread pointer iterator variable
*
* @warning Do not remove thread from wait queue when using this macro.
* Use @ref _WAIT_Q_FOR_EACH_SAFE instead if this is required.
*/
#define _WAIT_Q_FOR_EACH(wq, thread_ptr) \
SYS_DLIST_FOR_EACH_CONTAINER(&((wq)->waitq), thread_ptr, \
base.qnode_dlist)
/**
* Walk all threads pending on a wait queue.
*
* @note The iterator thread may be safely detached from the wait
* queue as part of the loop when using this macro.
*
* @warning `CONFIG_WAITQ_SCALABLE=n` is required to use this macro.
* Use it sparingly and make sure to have a fallback implementation
* which works when `CONFIG_WAITQ_SCALABLE=y`.
*
* @param wq Wait queue
* @param thread_ptr Thread pointer iterator variable
* @param loop_ptr Thread pointer variable used by loop
*/
#define _WAIT_Q_FOR_EACH_SAFE(wq, thread_ptr, loop_ptr) \
SYS_DLIST_FOR_EACH_CONTAINER_SAFE(&((wq)->waitq), thread_ptr, \
loop_ptr, base.qnode_dlist)
static inline void z_waitq_init(_wait_q_t *w)
{
sys_dlist_init(&w->waitq);
}
static inline struct k_thread *z_waitq_head(_wait_q_t *w)
{
return (struct k_thread *)sys_dlist_peek_head(&w->waitq);
}
#endif /* !CONFIG_WAITQ_SCALABLE */
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_KERNEL_INCLUDE_WAIT_Q_H_ */