qemu QLIST数据结构

简介: queue.h中是qemu使用到的一些基础的数据结构,比如QLIST,QSLIST,QSIMPLEQ,QTAILQ。 本文主要介绍QLIST的数据结构,其它几种数据结构与之类似。

queue.h中是qemu使用到的一些基础的数据结构,比如QLIST,QSLIST,QSIMPLEQ,QTAILQ。


本文主要介绍QLIST的数据结构,其它几种数据结构与之类似。

需要注意entry是嵌入在其他结构体(elm)中使用,QLIST是elm的链表,不是entry的链表。


HEAD

#define QLIST_HEAD(name, type)                                          \
struct name {                                                           \
        struct type *lh_first;  /* first element */                     \
}

lh_first表示list head first


head的静态初始化:

#define QLIST_HEAD_INITIALIZER(head)                                    \
        { NULL }


head的动态初始化:

#define QLIST_INIT(head) do {                                           \
        (head)->lh_first = NULL;                                        \
} while (/*CONSTCOND*/0)



ENTRY

#define QLIST_ENTRY(type)                                               \
struct {                                                                \
        struct type *le_next;   /* next element */                      \
        struct type **le_prev;  /* address of previous next element */  \
}

le_next表示list entry next,le_prev表示list entry prev

注意le_prev,是两个星号,是为了删除elm时的*(elm)->field.le_prev /*等效于之前一个elm的le_next*/ = (elm)->field.le_next;,可以在之后的示意图中详细看看。


elm是包含entry的结构体,比如:

typedef struct elm {
    QLIST_ENTRY(type) field;
    // other fields
} elm;

在head后面插入一个elm:

#define QLIST_INSERT_HEAD(head, elm, field) do {                        \
        if (((elm)->field.le_next = (head)->lh_first) != NULL)          \
                (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
        (head)->lh_first = (elm);                                       \
        (elm)->field.le_prev = &(head)->lh_first;                       \
} while (/*CONSTCOND*/0)


在某个listelm前面或者后面插入elm:

#define QLIST_INSERT_AFTER(listelm, elm, field) do {                    \
        if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)  \
                (listelm)->field.le_next->field.le_prev =               \
                    &(elm)->field.le_next;                              \
        (listelm)->field.le_next = (elm);                               \
        (elm)->field.le_prev = &(listelm)->field.le_next;               \
} while (/*CONSTCOND*/0)

#define QLIST_INSERT_BEFORE(listelm, elm, field) do {                   \
        (elm)->field.le_prev = (listelm)->field.le_prev;                \
        (elm)->field.le_next = (listelm);                               \
        *(listelm)->field.le_prev = (elm);                              \
        (listelm)->field.le_prev = &(elm)->field.le_next;               \
} while (/*CONSTCOND*/0)


删除elm:

#define QLIST_REMOVE(elm, field) do {                                   \
        if ((elm)->field.le_next != NULL)                               \
                (elm)->field.le_next->field.le_prev =                   \
                    (elm)->field.le_prev;                               \
        *(elm)->field.le_prev = (elm)->field.le_next;                   \
} while (/*CONSTCOND*/0)


遍历,safe模式的可以对本elm进行写操作,注意((next_var) = ((var)->field.le_next), 1),让&&后面的条件始终未1,防止next_var为NULL时,少循环一次:

#define QLIST_FOREACH(var, head, field)                                 \
        for ((var) = ((head)->lh_first);                                \
                (var);                                                  \
                (var) = ((var)->field.le_next))

#define QLIST_FOREACH_SAFE(var, head, field, next_var)                  \
        for ((var) = ((head)->lh_first);                                \
                (var) && ((next_var) = ((var)->field.le_next), 1);      \
                (var) = (next_var))


其他操作:

#define QLIST_EMPTY(head)                ((head)->lh_first == NULL)
#define QLIST_FIRST(head)                ((head)->lh_first)
#define QLIST_NEXT(elm, field)           ((elm)->field.le_next)


示意图:




QSLIST是单向链表,QTAILQ的头多了一个指向末尾的指针,不再赘述。


目录
相关文章
|
存储 算法 Linux
打破常规,Linux内核新的数据结构上场maple tree(下)
打破常规,Linux内核新的数据结构上场maple tree
|
存储 JavaScript 前端开发
数据结构之List | 让我们一块来学习数据结构
数据结构之List | 让我们一块来学习数据结构
140 0
|
6月前
|
存储 算法
【数据结构】数据结构概述
【数据结构】数据结构概述
67 1
|
6月前
|
存储 算法 Linux
Linux内核代码中常用的数据结构
Linux内核代码中常用的数据结构
107 0
|
存储 Linux 编译器
打破常规,Linux内核新的数据结构上场maple tree(上)
打破常规,Linux内核新的数据结构上场maple tree
|
存储 缓存 分布式计算
数据结构学习笔记(第一部分)
自学的时候对数据结构做了一些笔记记录~篇幅过长会分成多次发送哦~
数据结构学习笔记(第一部分)
|
算法 C语言 C++
数据结构1-3章学习笔记
数据结构1-3章学习遇到的问题即解决办法 主要包含链表,队列等问题 需要有一定的C语言基础,整个伪代码是C和C++混写的,所以一开始学会有点觉得难理解
134 1
数据结构1-3章学习笔记
|
缓存 算法
408数据结构学习笔记——外部排序
408数据结构学习笔记——外部排序
337 1
408数据结构学习笔记——外部排序