cleanup: include/: move misc/dlist.h to sys/dlist.h
move misc/dlist.h to sys/dlist.h and create a shim for backward-compatibility. No functional changes to the headers. A warning in the shim can be controlled with CONFIG_COMPAT_INCLUDES. Related to #16539 Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
parent
5d001f3e41
commit
ee9dd1a54a
30 changed files with 586 additions and 571 deletions
|
@ -35,7 +35,7 @@ extern "C" {
|
||||||
#include <kernel_internal.h>
|
#include <kernel_internal.h>
|
||||||
#include <zephyr/types.h>
|
#include <zephyr/types.h>
|
||||||
#include <misc/util.h>
|
#include <misc/util.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _ASMLANGUAGE
|
#ifndef _ASMLANGUAGE
|
||||||
|
|
|
@ -33,7 +33,7 @@ extern "C" {
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
#include <kernel_internal.h>
|
#include <kernel_internal.h>
|
||||||
#include <zephyr/types.h>
|
#include <zephyr/types.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#include <sys/atomic.h>
|
#include <sys/atomic.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ extern "C" {
|
||||||
#include <kernel_internal.h>
|
#include <kernel_internal.h>
|
||||||
#include <zephyr/types.h>
|
#include <zephyr/types.h>
|
||||||
#include <misc/util.h>
|
#include <misc/util.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* stacks */
|
/* stacks */
|
||||||
|
|
|
@ -28,7 +28,7 @@ extern "C" {
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
#include <zephyr/types.h>
|
#include <zephyr/types.h>
|
||||||
#include <misc/util.h>
|
#include <misc/util.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#include <kernel_internal.h>
|
#include <kernel_internal.h>
|
||||||
|
|
||||||
extern K_THREAD_STACK_DEFINE(_interrupt_stack, CONFIG_ISR_STACK_SIZE);
|
extern K_THREAD_STACK_DEFINE(_interrupt_stack, CONFIG_ISR_STACK_SIZE);
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
#include <kernel_internal.h>
|
#include <kernel_internal.h>
|
||||||
#include <zephyr/types.h>
|
#include <zephyr/types.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Some configurations require that the stack/registers be adjusted before
|
/* Some configurations require that the stack/registers be adjusted before
|
||||||
|
|
|
@ -33,7 +33,7 @@ extern "C" {
|
||||||
#include <kernel.h> /* public kernel API */
|
#include <kernel.h> /* public kernel API */
|
||||||
#include <kernel_internal.h>
|
#include <kernel_internal.h>
|
||||||
#include <zephyr/types.h>
|
#include <zephyr/types.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#include <misc/util.h>
|
#include <misc/util.h>
|
||||||
|
|
||||||
/* Bitmask definitions for the struct k_thread->flags bit field */
|
/* Bitmask definitions for the struct k_thread->flags bit field */
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#define ZEPHYR_INCLUDE_APP_MEMORY_APP_MEMDOMAIN_H_
|
#define ZEPHYR_INCLUDE_APP_MEMORY_APP_MEMDOMAIN_H_
|
||||||
|
|
||||||
#include <linker/linker-defs.h>
|
#include <linker/linker-defs.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
|
|
||||||
#ifdef CONFIG_USERSPACE
|
#ifdef CONFIG_USERSPACE
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
#include <zephyr/types.h>
|
#include <zephyr/types.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -26,7 +26,7 @@ typedef long long int off_t;
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#include <fs/fs_interface.h>
|
#include <fs/fs_interface.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include <sys/atomic.h>
|
#include <sys/atomic.h>
|
||||||
#include <sys/__assert.h>
|
#include <sys/__assert.h>
|
||||||
#include <sched_priq.h>
|
#include <sched_priq.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#include <misc/slist.h>
|
#include <misc/slist.h>
|
||||||
#include <misc/sflist.h>
|
#include <misc/sflist.h>
|
||||||
#include <misc/util.h>
|
#include <misc/util.h>
|
||||||
|
|
|
@ -1,554 +1,15 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2015 Wind River Systems, Inc.
|
* Copyright (c) 2019 Intel Corporation
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief Doubly-linked list implementation
|
|
||||||
*
|
|
||||||
* Doubly-linked list implementation using inline macros/functions.
|
|
||||||
* This API is not thread safe, and thus if a list is used across threads,
|
|
||||||
* calls to functions must be protected with synchronization primitives.
|
|
||||||
*
|
|
||||||
* The lists are expected to be initialized such that both the head and tail
|
|
||||||
* pointers point to the list itself. Initializing the lists in such a fashion
|
|
||||||
* simplifies the adding and removing of nodes to/from the list.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ZEPHYR_INCLUDE_MISC_DLIST_H_
|
#ifndef ZEPHYR_INCLUDE_MISC_DLIST_H_
|
||||||
#define ZEPHYR_INCLUDE_MISC_DLIST_H_
|
#define ZEPHYR_INCLUDE_MISC_DLIST_H_
|
||||||
|
|
||||||
#include <stddef.h>
|
#ifndef CONFIG_COMPAT_INCLUDES
|
||||||
#include <stdbool.h>
|
#warning "This header file has moved, include <sys/dlist.h> instead."
|
||||||
#include <toolchain.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct _dnode {
|
#include <sys/dlist.h>
|
||||||
union {
|
|
||||||
struct _dnode *head; /* ptr to head of list (sys_dlist_t) */
|
|
||||||
struct _dnode *next; /* ptr to next node (sys_dnode_t) */
|
|
||||||
};
|
|
||||||
union {
|
|
||||||
struct _dnode *tail; /* ptr to tail of list (sys_dlist_t) */
|
|
||||||
struct _dnode *prev; /* ptr to previous node (sys_dnode_t) */
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct _dnode sys_dlist_t;
|
|
||||||
typedef struct _dnode sys_dnode_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Provide the primitive to iterate on a list
|
|
||||||
* Note: the loop is unsafe and thus __dn should not be removed
|
|
||||||
*
|
|
||||||
* User _MUST_ add the loop statement curly braces enclosing its own code:
|
|
||||||
*
|
|
||||||
* SYS_DLIST_FOR_EACH_NODE(l, n) {
|
|
||||||
* <user code>
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* This and other SYS_DLIST_*() macros are not thread safe.
|
|
||||||
*
|
|
||||||
* @param __dl A pointer on a sys_dlist_t to iterate on
|
|
||||||
* @param __dn A sys_dnode_t pointer to peek each node of the list
|
|
||||||
*/
|
|
||||||
#define SYS_DLIST_FOR_EACH_NODE(__dl, __dn) \
|
|
||||||
for (__dn = sys_dlist_peek_head(__dl); __dn != NULL; \
|
|
||||||
__dn = sys_dlist_peek_next(__dl, __dn))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Provide the primitive to iterate on a list, from a node in the list
|
|
||||||
* Note: the loop is unsafe and thus __dn should not be removed
|
|
||||||
*
|
|
||||||
* User _MUST_ add the loop statement curly braces enclosing its own code:
|
|
||||||
*
|
|
||||||
* SYS_DLIST_ITERATE_FROM_NODE(l, n) {
|
|
||||||
* <user code>
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* Like SYS_DLIST_FOR_EACH_NODE(), but __dn already contains a node in the list
|
|
||||||
* where to start searching for the next entry from. If NULL, it starts from
|
|
||||||
* the head.
|
|
||||||
*
|
|
||||||
* This and other SYS_DLIST_*() macros are not thread safe.
|
|
||||||
*
|
|
||||||
* @param __dl A pointer on a sys_dlist_t to iterate on
|
|
||||||
* @param __dn A sys_dnode_t pointer to peek each node of the list;
|
|
||||||
* it contains the starting node, or NULL to start from the head
|
|
||||||
*/
|
|
||||||
#define SYS_DLIST_ITERATE_FROM_NODE(__dl, __dn) \
|
|
||||||
for (__dn = __dn ? sys_dlist_peek_next_no_check(__dl, __dn) \
|
|
||||||
: sys_dlist_peek_head(__dl); \
|
|
||||||
__dn != NULL; \
|
|
||||||
__dn = sys_dlist_peek_next(__dl, __dn))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Provide the primitive to safely iterate on a list
|
|
||||||
* Note: __dn can be removed, it will not break the loop.
|
|
||||||
*
|
|
||||||
* User _MUST_ add the loop statement curly braces enclosing its own code:
|
|
||||||
*
|
|
||||||
* SYS_DLIST_FOR_EACH_NODE_SAFE(l, n, s) {
|
|
||||||
* <user code>
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* This and other SYS_DLIST_*() macros are not thread safe.
|
|
||||||
*
|
|
||||||
* @param __dl A pointer on a sys_dlist_t to iterate on
|
|
||||||
* @param __dn A sys_dnode_t pointer to peek each node of the list
|
|
||||||
* @param __dns A sys_dnode_t pointer for the loop to run safely
|
|
||||||
*/
|
|
||||||
#define SYS_DLIST_FOR_EACH_NODE_SAFE(__dl, __dn, __dns) \
|
|
||||||
for (__dn = sys_dlist_peek_head(__dl), \
|
|
||||||
__dns = sys_dlist_peek_next(__dl, __dn); \
|
|
||||||
__dn != NULL; __dn = __dns, \
|
|
||||||
__dns = sys_dlist_peek_next(__dl, __dn))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @brief Provide the primitive to resolve the container of a list node
|
|
||||||
* Note: it is safe to use with NULL pointer nodes
|
|
||||||
*
|
|
||||||
* @param __dn A pointer on a sys_dnode_t to get its container
|
|
||||||
* @param __cn Container struct type pointer
|
|
||||||
* @param __n The field name of sys_dnode_t within the container struct
|
|
||||||
*/
|
|
||||||
#define SYS_DLIST_CONTAINER(__dn, __cn, __n) \
|
|
||||||
((__dn != NULL) ? CONTAINER_OF(__dn, __typeof__(*__cn), __n) : NULL)
|
|
||||||
/*
|
|
||||||
* @brief Provide the primitive to peek container of the list head
|
|
||||||
*
|
|
||||||
* @param __dl A pointer on a sys_dlist_t to peek
|
|
||||||
* @param __cn Container struct type pointer
|
|
||||||
* @param __n The field name of sys_dnode_t within the container struct
|
|
||||||
*/
|
|
||||||
#define SYS_DLIST_PEEK_HEAD_CONTAINER(__dl, __cn, __n) \
|
|
||||||
SYS_DLIST_CONTAINER(sys_dlist_peek_head(__dl), __cn, __n)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @brief Provide the primitive to peek the next container
|
|
||||||
*
|
|
||||||
* @param __dl A pointer on a sys_dlist_t to peek
|
|
||||||
* @param __cn Container struct type pointer
|
|
||||||
* @param __n The field name of sys_dnode_t within the container struct
|
|
||||||
*/
|
|
||||||
#define SYS_DLIST_PEEK_NEXT_CONTAINER(__dl, __cn, __n) \
|
|
||||||
((__cn != NULL) ? \
|
|
||||||
SYS_DLIST_CONTAINER(sys_dlist_peek_next(__dl, &(__cn->__n)), \
|
|
||||||
__cn, __n) : NULL)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Provide the primitive to iterate on a list under a container
|
|
||||||
* Note: the loop is unsafe and thus __cn should not be detached
|
|
||||||
*
|
|
||||||
* User _MUST_ add the loop statement curly braces enclosing its own code:
|
|
||||||
*
|
|
||||||
* SYS_DLIST_FOR_EACH_CONTAINER(l, c, n) {
|
|
||||||
* <user code>
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* @param __dl A pointer on a sys_dlist_t to iterate on
|
|
||||||
* @param __cn A pointer to peek each entry of the list
|
|
||||||
* @param __n The field name of sys_dnode_t within the container struct
|
|
||||||
*/
|
|
||||||
#define SYS_DLIST_FOR_EACH_CONTAINER(__dl, __cn, __n) \
|
|
||||||
for (__cn = SYS_DLIST_PEEK_HEAD_CONTAINER(__dl, __cn, __n); \
|
|
||||||
__cn != NULL; \
|
|
||||||
__cn = SYS_DLIST_PEEK_NEXT_CONTAINER(__dl, __cn, __n))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Provide the primitive to safely iterate on a list under a container
|
|
||||||
* Note: __cn can be detached, it will not break the loop.
|
|
||||||
*
|
|
||||||
* User _MUST_ add the loop statement curly braces enclosing its own code:
|
|
||||||
*
|
|
||||||
* SYS_DLIST_FOR_EACH_CONTAINER_SAFE(l, c, cn, n) {
|
|
||||||
* <user code>
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* @param __dl A pointer on a sys_dlist_t to iterate on
|
|
||||||
* @param __cn A pointer to peek each entry of the list
|
|
||||||
* @param __cns A pointer for the loop to run safely
|
|
||||||
* @param __n The field name of sys_dnode_t within the container struct
|
|
||||||
*/
|
|
||||||
#define SYS_DLIST_FOR_EACH_CONTAINER_SAFE(__dl, __cn, __cns, __n) \
|
|
||||||
for (__cn = SYS_DLIST_PEEK_HEAD_CONTAINER(__dl, __cn, __n), \
|
|
||||||
__cns = SYS_DLIST_PEEK_NEXT_CONTAINER(__dl, __cn, __n); \
|
|
||||||
__cn != NULL; __cn = __cns, \
|
|
||||||
__cns = SYS_DLIST_PEEK_NEXT_CONTAINER(__dl, __cn, __n))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief initialize list to its empty state
|
|
||||||
*
|
|
||||||
* @param list the doubly-linked list
|
|
||||||
*
|
|
||||||
* @return N/A
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline void sys_dlist_init(sys_dlist_t *list)
|
|
||||||
{
|
|
||||||
list->head = (sys_dnode_t *)list;
|
|
||||||
list->tail = (sys_dnode_t *)list;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SYS_DLIST_STATIC_INIT(ptr_to_list) { {(ptr_to_list)}, {(ptr_to_list)} }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief initialize node to its state when not in a list
|
|
||||||
*
|
|
||||||
* @param node the node
|
|
||||||
*
|
|
||||||
* @return N/A
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline void sys_dnode_init(sys_dnode_t *node)
|
|
||||||
{
|
|
||||||
node->next = NULL;
|
|
||||||
node->prev = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief check if a node is a member of any list
|
|
||||||
*
|
|
||||||
* @param node the node
|
|
||||||
*
|
|
||||||
* @return true if node is linked into a list, false if it is not
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline bool sys_dnode_is_linked(const sys_dnode_t *node)
|
|
||||||
{
|
|
||||||
return node->next != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief check if a node is the list's head
|
|
||||||
*
|
|
||||||
* @param list the doubly-linked list to operate on
|
|
||||||
* @param node the node to check
|
|
||||||
*
|
|
||||||
* @return true if node is the head, false otherwise
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline bool sys_dlist_is_head(sys_dlist_t *list, sys_dnode_t *node)
|
|
||||||
{
|
|
||||||
return list->head == node;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief check if a node is the list's tail
|
|
||||||
*
|
|
||||||
* @param list the doubly-linked list to operate on
|
|
||||||
* @param node the node to check
|
|
||||||
*
|
|
||||||
* @return true if node is the tail, false otherwise
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline bool sys_dlist_is_tail(sys_dlist_t *list, sys_dnode_t *node)
|
|
||||||
{
|
|
||||||
return list->tail == node;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief check if the list is empty
|
|
||||||
*
|
|
||||||
* @param list the doubly-linked list to operate on
|
|
||||||
*
|
|
||||||
* @return true if empty, false otherwise
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline bool sys_dlist_is_empty(sys_dlist_t *list)
|
|
||||||
{
|
|
||||||
return list->head == list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief check if more than one node present
|
|
||||||
*
|
|
||||||
* This and other sys_dlist_*() functions are not thread safe.
|
|
||||||
*
|
|
||||||
* @param list the doubly-linked list to operate on
|
|
||||||
*
|
|
||||||
* @return true if multiple nodes, false otherwise
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline bool sys_dlist_has_multiple_nodes(sys_dlist_t *list)
|
|
||||||
{
|
|
||||||
return list->head != list->tail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief get a reference to the head item in the list
|
|
||||||
*
|
|
||||||
* @param list the doubly-linked list to operate on
|
|
||||||
*
|
|
||||||
* @return a pointer to the head element, NULL if list is empty
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline sys_dnode_t *sys_dlist_peek_head(sys_dlist_t *list)
|
|
||||||
{
|
|
||||||
return sys_dlist_is_empty(list) ? NULL : list->head;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief get a reference to the head item in the list
|
|
||||||
*
|
|
||||||
* The list must be known to be non-empty.
|
|
||||||
*
|
|
||||||
* @param list the doubly-linked list to operate on
|
|
||||||
*
|
|
||||||
* @return a pointer to the head element
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline sys_dnode_t *sys_dlist_peek_head_not_empty(sys_dlist_t *list)
|
|
||||||
{
|
|
||||||
return list->head;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief get a reference to the next item in the list, node is not NULL
|
|
||||||
*
|
|
||||||
* Faster than sys_dlist_peek_next() if node is known not to be NULL.
|
|
||||||
*
|
|
||||||
* @param list the doubly-linked list to operate on
|
|
||||||
* @param node the node from which to get the next element in the list
|
|
||||||
*
|
|
||||||
* @return a pointer to the next element from a node, NULL if node is the tail
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline sys_dnode_t *sys_dlist_peek_next_no_check(sys_dlist_t *list,
|
|
||||||
sys_dnode_t *node)
|
|
||||||
{
|
|
||||||
return (node == list->tail) ? NULL : node->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief get a reference to the next item in the list
|
|
||||||
*
|
|
||||||
* @param list the doubly-linked list to operate on
|
|
||||||
* @param node the node from which to get the next element in the list
|
|
||||||
*
|
|
||||||
* @return a pointer to the next element from a node, NULL if node is the tail
|
|
||||||
* or NULL (when node comes from reading the head of an empty list).
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline sys_dnode_t *sys_dlist_peek_next(sys_dlist_t *list,
|
|
||||||
sys_dnode_t *node)
|
|
||||||
{
|
|
||||||
return (node != NULL) ? sys_dlist_peek_next_no_check(list, node) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief get a reference to the previous item in the list, node is not NULL
|
|
||||||
*
|
|
||||||
* Faster than sys_dlist_peek_prev() if node is known not to be NULL.
|
|
||||||
*
|
|
||||||
* @param list the doubly-linked list to operate on
|
|
||||||
* @param node the node from which to get the previous element in the list
|
|
||||||
*
|
|
||||||
* @return a pointer to the previous element from a node, NULL if node is the
|
|
||||||
* tail
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline sys_dnode_t *sys_dlist_peek_prev_no_check(sys_dlist_t *list,
|
|
||||||
sys_dnode_t *node)
|
|
||||||
{
|
|
||||||
return (node == list->head) ? NULL : node->prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief get a reference to the previous item in the list
|
|
||||||
*
|
|
||||||
* @param list the doubly-linked list to operate on
|
|
||||||
* @param node the node from which to get the previous element in the list
|
|
||||||
*
|
|
||||||
* @return a pointer to the previous element from a node, NULL if node is the
|
|
||||||
* tail or NULL (when node comes from reading the head of an empty
|
|
||||||
* list).
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline sys_dnode_t *sys_dlist_peek_prev(sys_dlist_t *list,
|
|
||||||
sys_dnode_t *node)
|
|
||||||
{
|
|
||||||
return (node != NULL) ? sys_dlist_peek_prev_no_check(list, node) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief get a reference to the tail item in the list
|
|
||||||
*
|
|
||||||
* @param list the doubly-linked list to operate on
|
|
||||||
*
|
|
||||||
* @return a pointer to the tail element, NULL if list is empty
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline sys_dnode_t *sys_dlist_peek_tail(sys_dlist_t *list)
|
|
||||||
{
|
|
||||||
return sys_dlist_is_empty(list) ? NULL : list->tail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief add node to tail of list
|
|
||||||
*
|
|
||||||
* This and other sys_dlist_*() functions are not thread safe.
|
|
||||||
*
|
|
||||||
* @param list the doubly-linked list to operate on
|
|
||||||
* @param node the element to append
|
|
||||||
*
|
|
||||||
* @return N/A
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline void sys_dlist_append(sys_dlist_t *list, sys_dnode_t *node)
|
|
||||||
{
|
|
||||||
node->next = list;
|
|
||||||
node->prev = list->tail;
|
|
||||||
|
|
||||||
list->tail->next = node;
|
|
||||||
list->tail = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief add node to head of list
|
|
||||||
*
|
|
||||||
* This and other sys_dlist_*() functions are not thread safe.
|
|
||||||
*
|
|
||||||
* @param list the doubly-linked list to operate on
|
|
||||||
* @param node the element to append
|
|
||||||
*
|
|
||||||
* @return N/A
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline void sys_dlist_prepend(sys_dlist_t *list, sys_dnode_t *node)
|
|
||||||
{
|
|
||||||
node->next = list->head;
|
|
||||||
node->prev = list;
|
|
||||||
|
|
||||||
list->head->prev = node;
|
|
||||||
list->head = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Insert a node into a list
|
|
||||||
*
|
|
||||||
* Insert a node before a specified node in a dlist.
|
|
||||||
*
|
|
||||||
* @param successor the position before which "node" will be inserted
|
|
||||||
* @param node the element to insert
|
|
||||||
*/
|
|
||||||
static inline void sys_dlist_insert(sys_dnode_t *successor, sys_dnode_t *node)
|
|
||||||
{
|
|
||||||
node->prev = successor->prev;
|
|
||||||
node->next = successor;
|
|
||||||
successor->prev->next = node;
|
|
||||||
successor->prev = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void __deprecated sys_dlist_insert_after(sys_dlist_t *list,
|
|
||||||
sys_dnode_t *insert_point, sys_dnode_t *node)
|
|
||||||
{
|
|
||||||
if (insert_point == NULL) {
|
|
||||||
sys_dlist_prepend(list, node);
|
|
||||||
} else {
|
|
||||||
node->next = insert_point->next;
|
|
||||||
node->prev = insert_point;
|
|
||||||
insert_point->next->prev = node;
|
|
||||||
insert_point->next = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void __deprecated sys_dlist_insert_before(sys_dlist_t *list,
|
|
||||||
sys_dnode_t *insert_point, sys_dnode_t *node)
|
|
||||||
{
|
|
||||||
if (insert_point == NULL) {
|
|
||||||
sys_dlist_append(list, node);
|
|
||||||
} else {
|
|
||||||
node->prev = insert_point->prev;
|
|
||||||
node->next = insert_point;
|
|
||||||
insert_point->prev->next = node;
|
|
||||||
insert_point->prev = node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief insert node at position
|
|
||||||
*
|
|
||||||
* Insert a node in a location depending on a external condition. The cond()
|
|
||||||
* function checks if the node is to be inserted _before_ the current node
|
|
||||||
* against which it is checked.
|
|
||||||
* This and other sys_dlist_*() functions are not thread safe.
|
|
||||||
*
|
|
||||||
* @param list the doubly-linked list to operate on
|
|
||||||
* @param node the element to insert
|
|
||||||
* @param cond a function that determines if the current node is the correct
|
|
||||||
* insert point
|
|
||||||
* @param data parameter to cond()
|
|
||||||
*
|
|
||||||
* @return N/A
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline void sys_dlist_insert_at(sys_dlist_t *list, sys_dnode_t *node,
|
|
||||||
int (*cond)(sys_dnode_t *node, void *data), void *data)
|
|
||||||
{
|
|
||||||
if (sys_dlist_is_empty(list)) {
|
|
||||||
sys_dlist_append(list, node);
|
|
||||||
} else {
|
|
||||||
sys_dnode_t *pos = sys_dlist_peek_head(list);
|
|
||||||
|
|
||||||
while ((pos != NULL) && (cond(pos, data) == 0)) {
|
|
||||||
pos = sys_dlist_peek_next(list, pos);
|
|
||||||
}
|
|
||||||
if (pos != NULL) {
|
|
||||||
sys_dlist_insert(pos, node);
|
|
||||||
} else {
|
|
||||||
sys_dlist_append(list, node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief remove a specific node from a list
|
|
||||||
*
|
|
||||||
* 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 remove
|
|
||||||
*
|
|
||||||
* @return N/A
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline void sys_dlist_remove(sys_dnode_t *node)
|
|
||||||
{
|
|
||||||
node->prev->next = node->next;
|
|
||||||
node->next->prev = node->prev;
|
|
||||||
sys_dnode_init(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief get the first node in a list
|
|
||||||
*
|
|
||||||
* This and other sys_dlist_*() functions are not thread safe.
|
|
||||||
*
|
|
||||||
* @param list the doubly-linked list to operate on
|
|
||||||
*
|
|
||||||
* @return the first node in the list, NULL if list is empty
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline sys_dnode_t *sys_dlist_get(sys_dlist_t *list)
|
|
||||||
{
|
|
||||||
sys_dnode_t *node = NULL;
|
|
||||||
|
|
||||||
if (!sys_dlist_is_empty(list)) {
|
|
||||||
node = list->head;
|
|
||||||
sys_dlist_remove(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* ZEPHYR_INCLUDE_MISC_DLIST_H_ */
|
#endif /* ZEPHYR_INCLUDE_MISC_DLIST_H_ */
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#define ZEPHYR_INCLUDE_SCHED_PRIQ_H_
|
#define ZEPHYR_INCLUDE_SCHED_PRIQ_H_
|
||||||
|
|
||||||
#include <misc/util.h>
|
#include <misc/util.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#include <misc/rb.h>
|
#include <misc/rb.h>
|
||||||
|
|
||||||
/* Two abstractions are defined here for "thread priority queues".
|
/* Two abstractions are defined here for "thread priority queues".
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
#include <zephyr.h>
|
#include <zephyr.h>
|
||||||
#include <misc/util.h>
|
#include <misc/util.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#include <sys/ring_buffer.h>
|
#include <sys/ring_buffer.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
|
554
include/sys/dlist.h
Normal file
554
include/sys/dlist.h
Normal file
|
@ -0,0 +1,554 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2015 Wind River Systems, Inc.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @brief Doubly-linked list implementation
|
||||||
|
*
|
||||||
|
* Doubly-linked list implementation using inline macros/functions.
|
||||||
|
* This API is not thread safe, and thus if a list is used across threads,
|
||||||
|
* calls to functions must be protected with synchronization primitives.
|
||||||
|
*
|
||||||
|
* The lists are expected to be initialized such that both the head and tail
|
||||||
|
* pointers point to the list itself. Initializing the lists in such a fashion
|
||||||
|
* simplifies the adding and removing of nodes to/from the list.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ZEPHYR_INCLUDE_SYS_DLIST_H_
|
||||||
|
#define ZEPHYR_INCLUDE_SYS_DLIST_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <toolchain.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct _dnode {
|
||||||
|
union {
|
||||||
|
struct _dnode *head; /* ptr to head of list (sys_dlist_t) */
|
||||||
|
struct _dnode *next; /* ptr to next node (sys_dnode_t) */
|
||||||
|
};
|
||||||
|
union {
|
||||||
|
struct _dnode *tail; /* ptr to tail of list (sys_dlist_t) */
|
||||||
|
struct _dnode *prev; /* ptr to previous node (sys_dnode_t) */
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _dnode sys_dlist_t;
|
||||||
|
typedef struct _dnode sys_dnode_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Provide the primitive to iterate on a list
|
||||||
|
* Note: the loop is unsafe and thus __dn should not be removed
|
||||||
|
*
|
||||||
|
* User _MUST_ add the loop statement curly braces enclosing its own code:
|
||||||
|
*
|
||||||
|
* SYS_DLIST_FOR_EACH_NODE(l, n) {
|
||||||
|
* <user code>
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* This and other SYS_DLIST_*() macros are not thread safe.
|
||||||
|
*
|
||||||
|
* @param __dl A pointer on a sys_dlist_t to iterate on
|
||||||
|
* @param __dn A sys_dnode_t pointer to peek each node of the list
|
||||||
|
*/
|
||||||
|
#define SYS_DLIST_FOR_EACH_NODE(__dl, __dn) \
|
||||||
|
for (__dn = sys_dlist_peek_head(__dl); __dn != NULL; \
|
||||||
|
__dn = sys_dlist_peek_next(__dl, __dn))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Provide the primitive to iterate on a list, from a node in the list
|
||||||
|
* Note: the loop is unsafe and thus __dn should not be removed
|
||||||
|
*
|
||||||
|
* User _MUST_ add the loop statement curly braces enclosing its own code:
|
||||||
|
*
|
||||||
|
* SYS_DLIST_ITERATE_FROM_NODE(l, n) {
|
||||||
|
* <user code>
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* Like SYS_DLIST_FOR_EACH_NODE(), but __dn already contains a node in the list
|
||||||
|
* where to start searching for the next entry from. If NULL, it starts from
|
||||||
|
* the head.
|
||||||
|
*
|
||||||
|
* This and other SYS_DLIST_*() macros are not thread safe.
|
||||||
|
*
|
||||||
|
* @param __dl A pointer on a sys_dlist_t to iterate on
|
||||||
|
* @param __dn A sys_dnode_t pointer to peek each node of the list;
|
||||||
|
* it contains the starting node, or NULL to start from the head
|
||||||
|
*/
|
||||||
|
#define SYS_DLIST_ITERATE_FROM_NODE(__dl, __dn) \
|
||||||
|
for (__dn = __dn ? sys_dlist_peek_next_no_check(__dl, __dn) \
|
||||||
|
: sys_dlist_peek_head(__dl); \
|
||||||
|
__dn != NULL; \
|
||||||
|
__dn = sys_dlist_peek_next(__dl, __dn))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Provide the primitive to safely iterate on a list
|
||||||
|
* Note: __dn can be removed, it will not break the loop.
|
||||||
|
*
|
||||||
|
* User _MUST_ add the loop statement curly braces enclosing its own code:
|
||||||
|
*
|
||||||
|
* SYS_DLIST_FOR_EACH_NODE_SAFE(l, n, s) {
|
||||||
|
* <user code>
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* This and other SYS_DLIST_*() macros are not thread safe.
|
||||||
|
*
|
||||||
|
* @param __dl A pointer on a sys_dlist_t to iterate on
|
||||||
|
* @param __dn A sys_dnode_t pointer to peek each node of the list
|
||||||
|
* @param __dns A sys_dnode_t pointer for the loop to run safely
|
||||||
|
*/
|
||||||
|
#define SYS_DLIST_FOR_EACH_NODE_SAFE(__dl, __dn, __dns) \
|
||||||
|
for (__dn = sys_dlist_peek_head(__dl), \
|
||||||
|
__dns = sys_dlist_peek_next(__dl, __dn); \
|
||||||
|
__dn != NULL; __dn = __dns, \
|
||||||
|
__dns = sys_dlist_peek_next(__dl, __dn))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief Provide the primitive to resolve the container of a list node
|
||||||
|
* Note: it is safe to use with NULL pointer nodes
|
||||||
|
*
|
||||||
|
* @param __dn A pointer on a sys_dnode_t to get its container
|
||||||
|
* @param __cn Container struct type pointer
|
||||||
|
* @param __n The field name of sys_dnode_t within the container struct
|
||||||
|
*/
|
||||||
|
#define SYS_DLIST_CONTAINER(__dn, __cn, __n) \
|
||||||
|
((__dn != NULL) ? CONTAINER_OF(__dn, __typeof__(*__cn), __n) : NULL)
|
||||||
|
/*
|
||||||
|
* @brief Provide the primitive to peek container of the list head
|
||||||
|
*
|
||||||
|
* @param __dl A pointer on a sys_dlist_t to peek
|
||||||
|
* @param __cn Container struct type pointer
|
||||||
|
* @param __n The field name of sys_dnode_t within the container struct
|
||||||
|
*/
|
||||||
|
#define SYS_DLIST_PEEK_HEAD_CONTAINER(__dl, __cn, __n) \
|
||||||
|
SYS_DLIST_CONTAINER(sys_dlist_peek_head(__dl), __cn, __n)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief Provide the primitive to peek the next container
|
||||||
|
*
|
||||||
|
* @param __dl A pointer on a sys_dlist_t to peek
|
||||||
|
* @param __cn Container struct type pointer
|
||||||
|
* @param __n The field name of sys_dnode_t within the container struct
|
||||||
|
*/
|
||||||
|
#define SYS_DLIST_PEEK_NEXT_CONTAINER(__dl, __cn, __n) \
|
||||||
|
((__cn != NULL) ? \
|
||||||
|
SYS_DLIST_CONTAINER(sys_dlist_peek_next(__dl, &(__cn->__n)), \
|
||||||
|
__cn, __n) : NULL)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Provide the primitive to iterate on a list under a container
|
||||||
|
* Note: the loop is unsafe and thus __cn should not be detached
|
||||||
|
*
|
||||||
|
* User _MUST_ add the loop statement curly braces enclosing its own code:
|
||||||
|
*
|
||||||
|
* SYS_DLIST_FOR_EACH_CONTAINER(l, c, n) {
|
||||||
|
* <user code>
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @param __dl A pointer on a sys_dlist_t to iterate on
|
||||||
|
* @param __cn A pointer to peek each entry of the list
|
||||||
|
* @param __n The field name of sys_dnode_t within the container struct
|
||||||
|
*/
|
||||||
|
#define SYS_DLIST_FOR_EACH_CONTAINER(__dl, __cn, __n) \
|
||||||
|
for (__cn = SYS_DLIST_PEEK_HEAD_CONTAINER(__dl, __cn, __n); \
|
||||||
|
__cn != NULL; \
|
||||||
|
__cn = SYS_DLIST_PEEK_NEXT_CONTAINER(__dl, __cn, __n))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Provide the primitive to safely iterate on a list under a container
|
||||||
|
* Note: __cn can be detached, it will not break the loop.
|
||||||
|
*
|
||||||
|
* User _MUST_ add the loop statement curly braces enclosing its own code:
|
||||||
|
*
|
||||||
|
* SYS_DLIST_FOR_EACH_CONTAINER_SAFE(l, c, cn, n) {
|
||||||
|
* <user code>
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @param __dl A pointer on a sys_dlist_t to iterate on
|
||||||
|
* @param __cn A pointer to peek each entry of the list
|
||||||
|
* @param __cns A pointer for the loop to run safely
|
||||||
|
* @param __n The field name of sys_dnode_t within the container struct
|
||||||
|
*/
|
||||||
|
#define SYS_DLIST_FOR_EACH_CONTAINER_SAFE(__dl, __cn, __cns, __n) \
|
||||||
|
for (__cn = SYS_DLIST_PEEK_HEAD_CONTAINER(__dl, __cn, __n), \
|
||||||
|
__cns = SYS_DLIST_PEEK_NEXT_CONTAINER(__dl, __cn, __n); \
|
||||||
|
__cn != NULL; __cn = __cns, \
|
||||||
|
__cns = SYS_DLIST_PEEK_NEXT_CONTAINER(__dl, __cn, __n))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief initialize list to its empty state
|
||||||
|
*
|
||||||
|
* @param list the doubly-linked list
|
||||||
|
*
|
||||||
|
* @return N/A
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline void sys_dlist_init(sys_dlist_t *list)
|
||||||
|
{
|
||||||
|
list->head = (sys_dnode_t *)list;
|
||||||
|
list->tail = (sys_dnode_t *)list;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SYS_DLIST_STATIC_INIT(ptr_to_list) { {(ptr_to_list)}, {(ptr_to_list)} }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief initialize node to its state when not in a list
|
||||||
|
*
|
||||||
|
* @param node the node
|
||||||
|
*
|
||||||
|
* @return N/A
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline void sys_dnode_init(sys_dnode_t *node)
|
||||||
|
{
|
||||||
|
node->next = NULL;
|
||||||
|
node->prev = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief check if a node is a member of any list
|
||||||
|
*
|
||||||
|
* @param node the node
|
||||||
|
*
|
||||||
|
* @return true if node is linked into a list, false if it is not
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline bool sys_dnode_is_linked(const sys_dnode_t *node)
|
||||||
|
{
|
||||||
|
return node->next != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief check if a node is the list's head
|
||||||
|
*
|
||||||
|
* @param list the doubly-linked list to operate on
|
||||||
|
* @param node the node to check
|
||||||
|
*
|
||||||
|
* @return true if node is the head, false otherwise
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline bool sys_dlist_is_head(sys_dlist_t *list, sys_dnode_t *node)
|
||||||
|
{
|
||||||
|
return list->head == node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief check if a node is the list's tail
|
||||||
|
*
|
||||||
|
* @param list the doubly-linked list to operate on
|
||||||
|
* @param node the node to check
|
||||||
|
*
|
||||||
|
* @return true if node is the tail, false otherwise
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline bool sys_dlist_is_tail(sys_dlist_t *list, sys_dnode_t *node)
|
||||||
|
{
|
||||||
|
return list->tail == node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief check if the list is empty
|
||||||
|
*
|
||||||
|
* @param list the doubly-linked list to operate on
|
||||||
|
*
|
||||||
|
* @return true if empty, false otherwise
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline bool sys_dlist_is_empty(sys_dlist_t *list)
|
||||||
|
{
|
||||||
|
return list->head == list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief check if more than one node present
|
||||||
|
*
|
||||||
|
* This and other sys_dlist_*() functions are not thread safe.
|
||||||
|
*
|
||||||
|
* @param list the doubly-linked list to operate on
|
||||||
|
*
|
||||||
|
* @return true if multiple nodes, false otherwise
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline bool sys_dlist_has_multiple_nodes(sys_dlist_t *list)
|
||||||
|
{
|
||||||
|
return list->head != list->tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief get a reference to the head item in the list
|
||||||
|
*
|
||||||
|
* @param list the doubly-linked list to operate on
|
||||||
|
*
|
||||||
|
* @return a pointer to the head element, NULL if list is empty
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline sys_dnode_t *sys_dlist_peek_head(sys_dlist_t *list)
|
||||||
|
{
|
||||||
|
return sys_dlist_is_empty(list) ? NULL : list->head;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief get a reference to the head item in the list
|
||||||
|
*
|
||||||
|
* The list must be known to be non-empty.
|
||||||
|
*
|
||||||
|
* @param list the doubly-linked list to operate on
|
||||||
|
*
|
||||||
|
* @return a pointer to the head element
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline sys_dnode_t *sys_dlist_peek_head_not_empty(sys_dlist_t *list)
|
||||||
|
{
|
||||||
|
return list->head;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief get a reference to the next item in the list, node is not NULL
|
||||||
|
*
|
||||||
|
* Faster than sys_dlist_peek_next() if node is known not to be NULL.
|
||||||
|
*
|
||||||
|
* @param list the doubly-linked list to operate on
|
||||||
|
* @param node the node from which to get the next element in the list
|
||||||
|
*
|
||||||
|
* @return a pointer to the next element from a node, NULL if node is the tail
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline sys_dnode_t *sys_dlist_peek_next_no_check(sys_dlist_t *list,
|
||||||
|
sys_dnode_t *node)
|
||||||
|
{
|
||||||
|
return (node == list->tail) ? NULL : node->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief get a reference to the next item in the list
|
||||||
|
*
|
||||||
|
* @param list the doubly-linked list to operate on
|
||||||
|
* @param node the node from which to get the next element in the list
|
||||||
|
*
|
||||||
|
* @return a pointer to the next element from a node, NULL if node is the tail
|
||||||
|
* or NULL (when node comes from reading the head of an empty list).
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline sys_dnode_t *sys_dlist_peek_next(sys_dlist_t *list,
|
||||||
|
sys_dnode_t *node)
|
||||||
|
{
|
||||||
|
return (node != NULL) ? sys_dlist_peek_next_no_check(list, node) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief get a reference to the previous item in the list, node is not NULL
|
||||||
|
*
|
||||||
|
* Faster than sys_dlist_peek_prev() if node is known not to be NULL.
|
||||||
|
*
|
||||||
|
* @param list the doubly-linked list to operate on
|
||||||
|
* @param node the node from which to get the previous element in the list
|
||||||
|
*
|
||||||
|
* @return a pointer to the previous element from a node, NULL if node is the
|
||||||
|
* tail
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline sys_dnode_t *sys_dlist_peek_prev_no_check(sys_dlist_t *list,
|
||||||
|
sys_dnode_t *node)
|
||||||
|
{
|
||||||
|
return (node == list->head) ? NULL : node->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief get a reference to the previous item in the list
|
||||||
|
*
|
||||||
|
* @param list the doubly-linked list to operate on
|
||||||
|
* @param node the node from which to get the previous element in the list
|
||||||
|
*
|
||||||
|
* @return a pointer to the previous element from a node, NULL if node is the
|
||||||
|
* tail or NULL (when node comes from reading the head of an empty
|
||||||
|
* list).
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline sys_dnode_t *sys_dlist_peek_prev(sys_dlist_t *list,
|
||||||
|
sys_dnode_t *node)
|
||||||
|
{
|
||||||
|
return (node != NULL) ? sys_dlist_peek_prev_no_check(list, node) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief get a reference to the tail item in the list
|
||||||
|
*
|
||||||
|
* @param list the doubly-linked list to operate on
|
||||||
|
*
|
||||||
|
* @return a pointer to the tail element, NULL if list is empty
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline sys_dnode_t *sys_dlist_peek_tail(sys_dlist_t *list)
|
||||||
|
{
|
||||||
|
return sys_dlist_is_empty(list) ? NULL : list->tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief add node to tail of list
|
||||||
|
*
|
||||||
|
* This and other sys_dlist_*() functions are not thread safe.
|
||||||
|
*
|
||||||
|
* @param list the doubly-linked list to operate on
|
||||||
|
* @param node the element to append
|
||||||
|
*
|
||||||
|
* @return N/A
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline void sys_dlist_append(sys_dlist_t *list, sys_dnode_t *node)
|
||||||
|
{
|
||||||
|
node->next = list;
|
||||||
|
node->prev = list->tail;
|
||||||
|
|
||||||
|
list->tail->next = node;
|
||||||
|
list->tail = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief add node to head of list
|
||||||
|
*
|
||||||
|
* This and other sys_dlist_*() functions are not thread safe.
|
||||||
|
*
|
||||||
|
* @param list the doubly-linked list to operate on
|
||||||
|
* @param node the element to append
|
||||||
|
*
|
||||||
|
* @return N/A
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline void sys_dlist_prepend(sys_dlist_t *list, sys_dnode_t *node)
|
||||||
|
{
|
||||||
|
node->next = list->head;
|
||||||
|
node->prev = list;
|
||||||
|
|
||||||
|
list->head->prev = node;
|
||||||
|
list->head = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Insert a node into a list
|
||||||
|
*
|
||||||
|
* Insert a node before a specified node in a dlist.
|
||||||
|
*
|
||||||
|
* @param successor the position before which "node" will be inserted
|
||||||
|
* @param node the element to insert
|
||||||
|
*/
|
||||||
|
static inline void sys_dlist_insert(sys_dnode_t *successor, sys_dnode_t *node)
|
||||||
|
{
|
||||||
|
node->prev = successor->prev;
|
||||||
|
node->next = successor;
|
||||||
|
successor->prev->next = node;
|
||||||
|
successor->prev = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void __deprecated sys_dlist_insert_after(sys_dlist_t *list,
|
||||||
|
sys_dnode_t *insert_point, sys_dnode_t *node)
|
||||||
|
{
|
||||||
|
if (insert_point == NULL) {
|
||||||
|
sys_dlist_prepend(list, node);
|
||||||
|
} else {
|
||||||
|
node->next = insert_point->next;
|
||||||
|
node->prev = insert_point;
|
||||||
|
insert_point->next->prev = node;
|
||||||
|
insert_point->next = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void __deprecated sys_dlist_insert_before(sys_dlist_t *list,
|
||||||
|
sys_dnode_t *insert_point, sys_dnode_t *node)
|
||||||
|
{
|
||||||
|
if (insert_point == NULL) {
|
||||||
|
sys_dlist_append(list, node);
|
||||||
|
} else {
|
||||||
|
node->prev = insert_point->prev;
|
||||||
|
node->next = insert_point;
|
||||||
|
insert_point->prev->next = node;
|
||||||
|
insert_point->prev = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief insert node at position
|
||||||
|
*
|
||||||
|
* Insert a node in a location depending on a external condition. The cond()
|
||||||
|
* function checks if the node is to be inserted _before_ the current node
|
||||||
|
* against which it is checked.
|
||||||
|
* This and other sys_dlist_*() functions are not thread safe.
|
||||||
|
*
|
||||||
|
* @param list the doubly-linked list to operate on
|
||||||
|
* @param node the element to insert
|
||||||
|
* @param cond a function that determines if the current node is the correct
|
||||||
|
* insert point
|
||||||
|
* @param data parameter to cond()
|
||||||
|
*
|
||||||
|
* @return N/A
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline void sys_dlist_insert_at(sys_dlist_t *list, sys_dnode_t *node,
|
||||||
|
int (*cond)(sys_dnode_t *node, void *data), void *data)
|
||||||
|
{
|
||||||
|
if (sys_dlist_is_empty(list)) {
|
||||||
|
sys_dlist_append(list, node);
|
||||||
|
} else {
|
||||||
|
sys_dnode_t *pos = sys_dlist_peek_head(list);
|
||||||
|
|
||||||
|
while ((pos != NULL) && (cond(pos, data) == 0)) {
|
||||||
|
pos = sys_dlist_peek_next(list, pos);
|
||||||
|
}
|
||||||
|
if (pos != NULL) {
|
||||||
|
sys_dlist_insert(pos, node);
|
||||||
|
} else {
|
||||||
|
sys_dlist_append(list, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief remove a specific node from a list
|
||||||
|
*
|
||||||
|
* 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 remove
|
||||||
|
*
|
||||||
|
* @return N/A
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline void sys_dlist_remove(sys_dnode_t *node)
|
||||||
|
{
|
||||||
|
node->prev->next = node->next;
|
||||||
|
node->next->prev = node->prev;
|
||||||
|
sys_dnode_init(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief get the first node in a list
|
||||||
|
*
|
||||||
|
* This and other sys_dlist_*() functions are not thread safe.
|
||||||
|
*
|
||||||
|
* @param list the doubly-linked list to operate on
|
||||||
|
*
|
||||||
|
* @return the first node in the list, NULL if list is empty
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline sys_dnode_t *sys_dlist_get(sys_dlist_t *list)
|
||||||
|
{
|
||||||
|
sys_dnode_t *node = NULL;
|
||||||
|
|
||||||
|
if (!sys_dlist_is_empty(list)) {
|
||||||
|
node = list->head;
|
||||||
|
sys_dlist_remove(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ZEPHYR_INCLUDE_SYS_DLIST_H_ */
|
|
@ -17,7 +17,7 @@
|
||||||
#define ZEPHYR_INCLUDE_SYS_CLOCK_H_
|
#define ZEPHYR_INCLUDE_SYS_CLOCK_H_
|
||||||
|
|
||||||
#include <misc/util.h>
|
#include <misc/util.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
#if !defined(_ASMLANGUAGE)
|
#if !defined(_ASMLANGUAGE)
|
||||||
#include <sys/atomic.h>
|
#include <sys/atomic.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#include <misc/rb.h>
|
#include <misc/rb.h>
|
||||||
#include <misc/util.h>
|
#include <misc/util.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#define ZEPHYR_KERNEL_INCLUDE_WAIT_Q_H_
|
#define ZEPHYR_KERNEL_INCLUDE_WAIT_Q_H_
|
||||||
|
|
||||||
#include <kernel_structs.h>
|
#include <kernel_structs.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#include <misc/rb.h>
|
#include <misc/rb.h>
|
||||||
#include <ksched.h>
|
#include <ksched.h>
|
||||||
#include <sched_priq.h>
|
#include <sched_priq.h>
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#include <ksched.h>
|
#include <ksched.h>
|
||||||
#include <version.h>
|
#include <version.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#include <kernel_internal.h>
|
#include <kernel_internal.h>
|
||||||
#include <kswap.h>
|
#include <kswap.h>
|
||||||
#include <drivers/entropy.h>
|
#include <drivers/entropy.h>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include <linker/sections.h>
|
#include <linker/sections.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <wait_q.h>
|
#include <wait_q.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
|
|
||||||
#if (CONFIG_NUM_MBOX_ASYNC_MSGS > 0)
|
#if (CONFIG_NUM_MBOX_ASYNC_MSGS > 0)
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include <toolchain.h>
|
#include <toolchain.h>
|
||||||
#include <linker/sections.h>
|
#include <linker/sections.h>
|
||||||
#include <wait_q.h>
|
#include <wait_q.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#include <ksched.h>
|
#include <ksched.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include <linker/sections.h>
|
#include <linker/sections.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <wait_q.h>
|
#include <wait_q.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#include <misc/math_extras.h>
|
#include <misc/math_extras.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
#include <syscall_handler.h>
|
#include <syscall_handler.h>
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
#include <toolchain.h>
|
#include <toolchain.h>
|
||||||
#include <linker/sections.h>
|
#include <linker/sections.h>
|
||||||
#include <wait_q.h>
|
#include <wait_q.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#include <debug/object_tracing_common.h>
|
#include <debug/object_tracing_common.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include <toolchain.h>
|
#include <toolchain.h>
|
||||||
#include <linker/sections.h>
|
#include <linker/sections.h>
|
||||||
#include <wait_q.h>
|
#include <wait_q.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
#include <syscall_handler.h>
|
#include <syscall_handler.h>
|
||||||
#include <sys/__assert.h>
|
#include <sys/__assert.h>
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include <ksched.h>
|
#include <ksched.h>
|
||||||
#include <syscall_handler.h>
|
#include <syscall_handler.h>
|
||||||
#include <misc/slist.h>
|
#include <misc/slist.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#include <misc/util.h>
|
#include <misc/util.h>
|
||||||
#include <sys/__assert.h>
|
#include <sys/__assert.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#include <toolchain.h>
|
#include <toolchain.h>
|
||||||
#include <linker/sections.h>
|
#include <linker/sections.h>
|
||||||
#include <wait_q.h>
|
#include <wait_q.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#include <ksched.h>
|
#include <ksched.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
#include <syscall_handler.h>
|
#include <syscall_handler.h>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#include <misc/mempool_base.h>
|
#include <misc/mempool_base.h>
|
||||||
|
|
||||||
#include "hal/cntr.h"
|
#include "hal/cntr.h"
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#include <misc/mempool_base.h>
|
#include <misc/mempool_base.h>
|
||||||
|
|
||||||
#include "util/mem.h"
|
#include "util/mem.h"
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#include <misc/mempool_base.h>
|
#include <misc/mempool_base.h>
|
||||||
#include <toolchain.h>
|
#include <toolchain.h>
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
#include <misc/mempool_base.h>
|
#include <misc/mempool_base.h>
|
||||||
|
|
||||||
#include "hal/cntr.h"
|
#include "hal/cntr.h"
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ztest.h>
|
#include <ztest.h>
|
||||||
#include <misc/dlist.h>
|
#include <sys/dlist.h>
|
||||||
|
|
||||||
static sys_dlist_t test_list;
|
static sys_dlist_t test_list;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue