RT-Thread - rtservice.h分析

  本笔记作为自己的学习记录,纯属个人理解。

  rtservice.h是 RT_Thread中关于双向链表和单相链表的相关定义。

  双向链表主要实现了节点插入、删除、是否为空、计算链表长度的功能。这里主要分析一下是否为空、计算链表长度的功能。

  是否为空:

1 rt_inline int rt_list_isempty(const rt_list_t *l)
2 {
3     return l->next == l;
4 }

  计算链表长度:

 1 rt_inline unsigned int rt_list_len(const rt_list_t *l)
 2 {
 3     unsigned int len = 0;
 4     const rt_list_t *p = l;
 5     while (p->next != l)
 6     {
 7         p = p->next;
 8         len ++;
 9     }
10 
11     return len;
12 }

  这里输入的变量 const rt_list_t *l 其实是一个链表节点,这个节点作为链表头节点在使用时候创建,并初始化为指向本身,这个节点是一直存在的,也即链表至少有一个头节点存在。理解了这一点上边两个函数就好理解了。

  下面在看一个重要的宏 rt_list_entry,这个宏本质是 rt_container_of,获取list的拥有者的入口地址。

1 #define rt_list_entry(node, type, member) \
2     rt_container_of(node, type, member)
1 #define rt_container_of(ptr, type, member) \
2     ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))

  例如如下一个结构体

1 struct obj {
2     uint8_t m1;
3     uint8_t m2;
4     uint8_t m3;
5     uint8_t m4;
6     rt_list_t list;
7     ...
8 };

  (char *)(ptr):ptr 是一个指向list的指针,转换为一个char 类型的指针;

  (type *)0:等价于将0转换为一个指向 obj 类型变量的指针,且变量存储地址为0;

  (type *)0)->member:获取 obj 类型的member元素,即 list 元素;

  &((type *)0)->member:获取 obj 类型的 list 元素的地址,由于首地址为0,所以这个地址也是 list 元素相对于结构体变量的存储地址的偏移地址

  (char *)(ptr) - (unsigned long)(&((type *)0)->member)):指向list的指针 减去 偏移地址,就指向了 list 元素所在结构体的存储地址,也即得到了结构体变量指针

  其内存地址空间如下:

 

   

  单相链表的内容相对好理解一些,就不再赘述了。下面是rtservice.h的部分代码,仅供参考

  1 #define rt_container_of(ptr, type, member) \
  2     ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
  3     
  4 #define RT_LIST_OBJECT_INIT(object) { &(object), &(object) }
  5 
  6 rt_inline void rt_list_init(rt_list_t *l)
  7 {
  8     l->next = l->prev = l;
  9 }
 10 
 11 rt_inline void rt_list_insert_after(rt_list_t *l, rt_list_t *n)
 12 {
 13     l->next->prev = n;
 14     n->next = l->next;
 15 
 16     l->next = n;
 17     n->prev = l;
 18 }
 19 
 20 rt_inline void rt_list_insert_before(rt_list_t *l, rt_list_t *n)
 21 {
 22     l->prev->next = n;
 23     n->prev = l->prev;
 24 
 25     l->prev = n;
 26     n->next = l;
 27 }
 28 
 29 rt_inline void rt_list_remove(rt_list_t *n)
 30 {
 31     n->next->prev = n->prev;
 32     n->prev->next = n->next;
 33 
 34     n->next = n->prev = n;
 35 }
 36 
 37 rt_inline int rt_list_isempty(const rt_list_t *l)
 38 {
 39     return l->next == l;
 40 }
 41 
 42 rt_inline unsigned int rt_list_len(const rt_list_t *l)
 43 {
 44     unsigned int len = 0;
 45     const rt_list_t *p = l;
 46     while (p->next != l)
 47     {
 48         p = p->next;
 49         len ++;
 50     }
 51 
 52     return len;
 53 }
 54 
 55 #define rt_list_entry(node, type, member) \
 56     rt_container_of(node, type, member)
 57 
 58 #define rt_list_for_each(pos, head) \
 59     for (pos = (head)->next; pos != (head); pos = pos->next)
 60 
 61 rt_inline void rt_slist_init(rt_slist_t *l)
 62 {
 63     l->next = RT_NULL;
 64 }
 65 
 66 rt_inline void rt_slist_append(rt_slist_t *l, rt_slist_t *n)
 67 {
 68     struct rt_slist_node *node;
 69 
 70     node = l;
 71     while (node->next) node = node->next;
 72 
 73     /* append the node to the tail */
 74     node->next = n;
 75     n->next = RT_NULL;
 76 }
 77 
 78 rt_inline void rt_slist_insert(rt_slist_t *l, rt_slist_t *n)
 79 {
 80     n->next = l->next;
 81     l->next = n;
 82 }
 83 
 84 rt_inline unsigned int rt_slist_len(const rt_slist_t *l)
 85 {
 86     unsigned int len = 0;
 87     const rt_slist_t *list = l->next;
 88     while (list != RT_NULL)
 89     {
 90         list = list->next;
 91         len ++;
 92     }
 93 
 94     return len;
 95 }
 96 
 97 rt_inline rt_slist_t *rt_slist_remove(rt_slist_t *l, rt_slist_t *n)
 98 {
 99     /* remove slist head */
100     struct rt_slist_node *node = l;
101     while (node->next && node->next != n) node = node->next;
102 
103     /* remove node */
104     if (node->next != (rt_slist_t *)0) node->next = node->next->next;
105 
106     return l;
107 }
108 
109 rt_inline rt_slist_t *rt_slist_first(rt_slist_t *l)
110 {
111     return l->next;
112 }
113 
114 rt_inline rt_slist_t *rt_slist_tail(rt_slist_t *l)
115 {
116     while (l->next) l = l->next;
117 
118     return l;
119 }
120 
121 rt_inline rt_slist_t *rt_slist_next(rt_slist_t *n)
122 {
123     return n->next;
124 }
125 
126 rt_inline int rt_slist_isempty(rt_slist_t *l)
127 {
128     return l->next == RT_NULL;
129 }
130 
131 #define rt_slist_entry(node, type, member) \
132     rt_container_of(node, type, member)

 

posted @ 2022-05-18 14:37  Ivan0512  阅读(178)  评论(0编辑  收藏  举报