static
inline
void sys_slist_init(sys_slist_t *list)
|
static
inline
bool sys_slist_is_empty(sys_slist_t *list)
|
static
inline sys_snode_t *sys_slist_peek_head(sys_slist_t *list)
|
static
inline sys_snode_t *sys_slist_peek_tail(sys_slist_t *list)
|
static
inline sys_snode_t *sys_slist_peek_next_no_check(sys_snode_t *node)
|
static
inline sys_snode_t *sys_slist_peek_next(sys_snode_t *node)
|
static
inline
void sys_slist_append(sys_slist_t *list,
sys_snode_t *node) |
static
inline
void sys_slist_prepend(sys_slist_t *list,
sys_snode_t *node) |
static
inline
void sys_slist_append_list(sys_slist_t *list,
void *head, void *tail) { if (!list->tail) { list->head = (sys_snode_t *)head; list->tail = (sys_snode_t *)tail; } else { list->tail->next = (sys_snode_t *)head; list->tail = (sys_snode_t *)tail; } } |
static
inline
void sys_slist_merge_slist(sys_slist_t *list,
sys_slist_t *list_to_append) { sys_slist_append_list(list, list_to_append->head, list_to_append->tail); sys_slist_init(list); } |
static
inline
void sys_slist_insert(sys_slist_t *list,
sys_snode_t *prev, sys_snode_t *node) |
static
inline sys_snode_t *sys_slist_get_not_empty(sys_slist_t *list)
|
static
inline sys_snode_t *sys_slist_get(sys_slist_t *list)
|
static
inline
void sys_slist_remove(sys_slist_t *list,
sys_snode_t *prev_node, sys_snode_t *node) |
static
inline
void sys_slist_find_and_remove(sys_slist_t *list,
sys_snode_t *node) |
#ifndef __SLIST_H__
#define __SLIST_H__ /** * @brief 遍历整张链表 * Note: 循环不安全,因此__sn不能被,简而言之就是不能用于删除操作。 * * 用户必须自行添加大括号以指定循环体 * * SYS_SLIST_FOR_EACH_NODE(l, n) { * * } * * @param __sl 指向sys_slist_t类型的指针,表示将进行迭代的链表 * @param __sn sys_snode_t类型指针,用于遍历链表中的每个节点 */ #define SYS_SLIST_FOR_EACH_NODE(__sl, __sn) \ for (__sn = sys_slist_peek_head(__sl); __sn; \ __sn = sys_slist_peek_next(__sn)) /** * @brief 从链表指定节点处遍历到结尾 * Note: 循环不安全,因此__sn不能被删除,简而言之就是不能用于删除操作。 * * 用户自行加大括号 * * SYS_SLIST_ITERATE_FROM_NODE(l, n) { * * } * * 和SYS_SLIST_FOR_EACH_NODE()一样, 但如__sn指定为链表中的一个节点, * 则遍历从__sn的下一个节点开始。如果__sn为空,则从头节点开始遍历。 * * @param __sl 指向sys_slist_t类型的指针,表示将进行迭代的链 * @param __sn sys_snode_t类型指针,指定的开始节点,为空则从头开始 */ #define SYS_SLIST_ITERATE_FROM_NODE(__sl, __sn) \ for (__sn = __sn ? sys_slist_peek_next_no_check(__sn) \ : sys_slist_peek_head(__sl); \ __sn; \ __sn = sys_slist_peek_next(__sn)) /** * @brief 安全地遍历整个链表 * Note: __sn可被删除, 它不会打断循环. * * 用户必须自行添加大括号: * * SYS_SLIST_FOR_EACH_NODE_SAFE(l, n, s) { * * } * * @param __sl sys_slist_t类型指针,指向被遍历链表 * @param __sn sys_snode_t类型指针,依次等于链表中的每个节点 * @param __sns sys_snode_t类型指针,用于安全遍历 */ #define SYS_SLIST_FOR_EACH_NODE_SAFE(__sl, __sn, __sns) \ for (__sn = sys_slist_peek_head(__sl), \ __sns = sys_slist_peek_next(__sn); \ __sn; __sn = __sns, \ __sns = sys_slist_peek_next(__sn)) |
/** * @brief 提供根据容器建立的链表的遍历原语 * Note: 此循环不安全,因此不能被删除 * * 用户必须自行加大括号: * * SYS_SLIST_FOR_EACH_CONTAINER(l, c, n) { * * } * * @param __sl sys_slist_t指针,将遍历此链表 * @param __cn 用于遍历链表元素的临时指针变量,为容器类型 * @param __n sys_node_t在容器结构体中的类型名称 */ #define SYS_SLIST_FOR_EACH_CONTAINER(__sl, __cn, __n) \ for (__cn = SYS_SLIST_PEEK_HEAD_CONTAINER(__sl, __cn, __n); __cn; \ __cn = SYS_SLIST_PEEK_NEXT_CONTAINER(__cn, __n)) |
/** * @brief 提供根据容器建立的链表的安全遍历原语 * Note: __cn 可以被删除,不会打断循环. * * User 用户必须自行添加大括号: * * SYS_SLIST_FOR_EACH_NODE_SAFE(l, c, cn, n) { * * } * * @param __sl sys_slist_t类型指针,将遍历此链表 * @param __cn 用于遍历链表元素的临时指针变量,为容器类型 * @param __cns 用于安全遍历的临时变量,和__cn同类型 * @param __n sys_node_t在容器结构体中的类型名称 */ #define SYS_SLIST_FOR_EACH_CONTAINER_SAFE(__sl, __cn, __cns, __n) \ for (__cn = SYS_SLIST_PEEK_HEAD_CONTAINER(__sl, __cn, __n), \ __cns = SYS_SLIST_PEEK_NEXT_CONTAINER(__cn, __n); __cn; \ __cn = __cns, __cns = SYS_SLIST_PEEK_NEXT_CONTAINER(__cn, __n)) |
先上代码:
#include
#include
#include
static sys_slist_t list;
struct container_node
{
sys_snode_t node;
int id;
};
void PrintList(sys_slist_t *list) //依次打印所有节点
{
struct container_node *container;
printk("print list node:\n");
SYS_SLIST_FOR_EACH_CONTAINER(list, container, node)
{
printk("node%d ", container->id);
}
printk("\n\n");
}
void main(void)
{
struct container_node node1, node2, node3, node4, node5;
node1.id = 1;
node2.id = 2;
node3.id = 3;
node4.id = 4;
node5.id = 5;
sys_slist_init(&list);
//将5个节点加入链表
sys_slist_append(&list, &node1.node);
sys_slist_append(&list, &node2.node);
sys_slist_append(&list, &node3.node);
sys_slist_append(&list, &node4.node);
sys_slist_append(&list, &node5.node);
PrintList(&list);
printk("move node3 to head\n");
sys_slist_find_and_remove(&list, &node3.node);//删除节点3
sys_slist_prepend(&list, &node3.node);//将节点3变为头节点
PrintList(&list);
printk("switch node4 and node2\n");
sys_slist_find_and_remove(&list, &node4.node);//删除节点4
sys_slist_insert(&list, &node1.node, &node4.node);//将节点4加到节点1后面
PrintList(&list);
}
先记下环境变量设置命令,方便以后回来对照:
export ZEPHYR_GCC_VARIANT=zephyr
export ZEPHYR_SDK_INSTALL_DIR=~/zephyr-sdk cd zephyr-project/ source zephyr-env.sh |
make BOARD=qemu_x86 qemu
|