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) { * <user code> * } * * @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) { * <user code> * } * * 和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) { * <user code> * } * * @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) { * <user code> * } * * @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) { * <user code> * } * * @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 <zephyr.h>
#include <misc/printk.h>
#include <misc/slist.h>
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
|