码迷,mamicode.com
首页 > 其他好文 > 详细

内核链表

时间:2018-05-25 17:52:17      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:ret   rev   计算   data   member   ring   poi   argv   服务   

1 引言

  如果大家用c做应用(哈哈,估计基本不用),就会发现总要造轮子,本着服务大家,方便自己的原则,搞点小程序方便大家做开发。

  这里就泼个内核链表的实现给大家(程序如果有问题,希望大家及时指正)使用。

  为啥要用内核链表?

  主要还是为了方便,比如用c做个项目需要多次用到链表,注意这里的意思是多个链表中的数据类型不同,format as:

struct StringList {
       char str[256];
       struct UserList* pre;
       struct UserList* next;  
};

strcut IntList {
       int id;
       struct Intlist* pre;      
       struct Intlist* next;
};    

  需要实现两个链表的逻辑,因为链表是“数据相关”(自创词)的。

  内核链表是数据无关的,基本原理是通过结构体的一个元素地址从而可以获取结构体入口地址,这块不清楚的老铁自行查一下container_of这个宏,这里不再啰嗦。

2  扣出内核中的链表实现

# define POISON_POINTER_DELTA 0

#define LIST_POISON1  ((void *) 0x00100100 + POISON_POINTER_DELTA)
#define LIST_POISON2  ((void *) 0x00200200 + POISON_POINTER_DELTA)

//计算member在type中的位置
#define offsetof(type, member)  (size_t)(&((type*)0)->member)
//根据member的地址获取type的起始地址 #define container_of(ptr, type, member) ({ const typeof(((type *)0)->member)*__mptr = (ptr); (type *)((char *)__mptr - offsetof(type, member)); }) #define list_entry(ptr, type, member) \ container_of(ptr, type, member) #define list_first_entry(ptr, type, member) \ list_entry((ptr)->next, type, member) #define list_for_each(pos, head) for (pos = (head)->next; pos != (head); pos = pos->next) //链表结构 struct list_head { struct list_head *prev; struct list_head *next; }; static inline void init_list_head(struct list_head *list) { list->prev = list; list->next = list; } static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) prev->next = new; new->prev = prev; new->next = next; next->prev = new; } //从头部添加 static inline void list_add(struct list_head *new , struct list_head *head) { __list_add(new, head, head->next); } //从尾部添加 static inline void list_add_tail(struct list_head *new, struct list_head *head) { __list_add(new, head->prev, head); } static inline void __list_del(struct list_head *prev, struct list_head *next) { prev->next = next; next->prev = prev; } static inline void list_del(struct list_head *entry) { __list_del(entry->prev, entry->next); entry->next = LIST_POISON1; entry->prev = LIST_POISON2; } static inline void list_move(struct list_head *list, struct list_head *head) { __list_del(list->prev, list->next); list_add(list, head); } static inline void list_move_tail(struct list_head *list, struct list_head *head) { __list_del(list->prev, list->next); list_add_tail(list, head); }
//An example
int main(int argc, const char* argv[])
{
  //Init List Head
  struct list_head* global_head = (struct list_head*)malloc(sizeof(struct list_head));
  init_list_head(global_head);

  //Insert an value from tail
  struct Val {
    struct list_head node;
    int value;        //Identify your data on list
  };
  
  struct Val* v = (struct Val*)malloc(sizeof(struct Val));
  
  struct list_head* node = v->node;
  list_add_tail(node, global_head);
  
  //travel the list.
  struct list_head* p;
  list_for_each(pos, global_head)
  {
    v = list_entry(pos, struct Val, value);
    printf("%d ", v->value);
  }
  fputs();

  return 0;
}

 

    

 

内核链表

标签:ret   rev   计算   data   member   ring   poi   argv   服务   

原文地址:https://www.cnblogs.com/myJune/p/9089927.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!