当前位置: 首页 > news >正文

内核链表在用户程序中的移植和使用

基础知识

struct list_head {struct list_head *next, *prev;
};

初始化:

#define LIST_HEAD_INIT(name) { (name)->next = (name); (name)->prev = (name);}

相比于下面这样初始化,前面初始化的好处是,处理链表的时候,不用判空了。太厉害了。

#define LIST_HEAD_INIT(name) { (name)->next = (NULL); (name)->prev = (NULL);}

 遍历链表:

/*** list_for_each	-	iterate over a list* @pos:	the &struct list_head to use as a loop cursor.* @head:	the head for your list.*/
#define list_for_each(pos, head) \for (pos = (head)->next; pos != (head); pos = pos->next)

添加节点:(表头开始添加)

/** Insert a new entry between two known consecutive entries.** This is only for internal list manipulation where we know* the prev/next entries already!*/
static inline void __list_add(struct list_head *new,struct list_head *prev,struct list_head *next)
{next->prev = new;new->next = next;new->prev = prev;prev->next = new;
}/*** list_add - add a new entry* @new: new entry to be added* @head: list head to add it after** Insert a new entry after the specified head.* This is good for implementing stacks.*/
static inline void list_add(struct list_head *new, struct list_head *head)
{__list_add(new, head, head->next);
}

添加节点:(表尾开始添加) 

/** Insert a new entry between two known consecutive entries.** This is only for internal list manipulation where we know* the prev/next entries already!*/
static inline void __list_add(struct list_head *new,struct list_head *prev,struct list_head *next)
{next->prev = new;new->next = next;new->prev = prev;prev->next = new;
}
/*** list_add_tail - add a new entry* @new: new entry to be added* @head: list head to add it before** Insert a new entry before the specified head.* This is useful for implementing queues.*/
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{__list_add(new, head->prev, head);
}

删除节点

/** Delete a list entry by making the prev/next entries* point to each other.** This is only for internal list manipulation where we know* the prev/next entries already!*/
static inline void __list_del(struct list_head * prev, struct list_head * next)
{next->prev = prev;prev->next = next;
}static inline void list_del(struct list_head *entry)
{__list_del(entry->prev, entry->next);LIST_HEAD_INIT(entry);
}

判空:

/*** list_empty - tests whether a list is empty* @head: the list to test.*/
static int list_empty(const struct list_head *head)
{return (head->next) == head;
}

基本功能就这些了

测试代码

#include <stdio.h>
#include <stdlib.h>#define _DEBUG_INFO
#ifdef _DEBUG_INFO#define DEBUG_INFO(format,...)	\printf("%s:%d -- "format"\n",\__func__,__LINE__,##__VA_ARGS__)
#else#define DEBUG_INFO(format,...)
#endifstruct list_head {struct list_head *next, *prev;
};struct rcu_private_data{struct list_head list;
};struct my_list_node{struct list_head node;int number;
};/*** list_for_each	-	iterate over a list* @pos:	the &struct list_head to use as a loop cursor.* @head:	the head for your list.*/
#define list_for_each(pos, head) \for (pos = (head)->next; pos != (head); pos = pos->next)#define LIST_HEAD_INIT(name) { (name)->next = (name); (name)->prev = (name);}#define offsetof(TYPE, MEMBER)	((size_t)&((TYPE *)0)->MEMBER)
#define container_of(ptr, type, member) ({				\void *__mptr = (void *)(ptr);					\((type *)(__mptr - offsetof(type, member))); })/*** list_empty - tests whether a list is empty* @head: the list to test.*/
static int list_empty(const struct list_head *head)
{return (head->next) == head;
}/** Insert a new entry between two known consecutive entries.** This is only for internal list manipulation where we know* the prev/next entries already!*/
static inline void __list_add(struct list_head *new,struct list_head *prev,struct list_head *next)
{next->prev = new;new->next = next;new->prev = prev;prev->next = new;
}/*** list_add - add a new entry* @new: new entry to be added* @head: list head to add it after** Insert a new entry after the specified head.* This is good for implementing stacks.*/
static inline void list_add(struct list_head *new, struct list_head *head)
{__list_add(new, head, head->next);
}/*** list_add_tail - add a new entry* @new: new entry to be added* @head: list head to add it before** Insert a new entry before the specified head.* This is useful for implementing queues.*/
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{__list_add(new, head->prev, head);
}/** Delete a list entry by making the prev/next entries* point to each other.** This is only for internal list manipulation where we know* the prev/next entries already!*/
static inline void __list_del(struct list_head * prev, struct list_head * next)
{next->prev = prev;prev->next = next;
}static inline void list_del(struct list_head *entry)
{__list_del(entry->prev, entry->next);LIST_HEAD_INIT(entry);
}static int list_size(struct rcu_private_data *p){struct list_head *pos;struct list_head *head = &p->list;int count = 0;if(list_empty(&p->list)){DEBUG_INFO("list is empty");return 0;}list_for_each(pos,head){count++;}return count;
}static int show_list_nodes(struct rcu_private_data *p){struct list_head *pos;struct list_head *head = &p->list;int count = 0;struct my_list_node *pnode;if(list_empty(&p->list)){DEBUG_INFO("list is empty");return 0;}list_for_each(pos,head){pnode = (struct my_list_node*)container_of(pos,struct my_list_node,node);DEBUG_INFO("pnode->number = %d",pnode->number);count++;}return count;
}int main(int argc, char **argv){int i = 0;static struct my_list_node * new[6];struct rcu_private_data *p = (struct rcu_private_data*)malloc(sizeof(struct rcu_private_data));LIST_HEAD_INIT(&p->list);DEBUG_INFO("list_empty(&p->list) = %d",list_empty(&p->list));for(i = 0;i < 3;i++){new[i] = (struct my_list_node*)malloc(sizeof(struct my_list_node));LIST_HEAD_INIT(&new[i]->node);new[i]->number = i;list_add(&new[i]->node,&p->list);}for(i = 3;i < 6;i++){new[i] = (struct my_list_node*)malloc(sizeof(struct my_list_node));LIST_HEAD_INIT(&new[i]->node);new[i]->number = i;list_add_tail(&new[i]->node,&p->list);}//输出链表节点数DEBUG_INFO("list_size(&p->list) = %d",list_size(p));//遍历链表show_list_nodes(p);//删除指定节点list_del(&new[3]->node);DEBUG_INFO("list_size(&p->list) = %d",list_size(p));//遍历链表show_list_nodes(p);for(i = 0;i < 6;i++){list_del(&new[i]->node);}DEBUG_INFO("list_size(&p->list) = %d",list_size(p));//遍历链表show_list_nodes(p);for(i = 0;i < 6;i++){free(new[i]);}free(p);return 0;
}

 编译

gcc -o app app.c

执行结果:

 小结

http://www.lryc.cn/news/98427.html

相关文章:

  • 使用C#基于ComPDFKit SDK快速构建PDF阅读器
  • el-tabel导出excel表格
  • 双击start.bat文件闪退,运行报错“unable to access jarfile”
  • 大数据Flink(五十一):Flink的引入和Flink的简介
  • c语言的数据类型 -- 与GPT对话
  • Truffle 进行智能合约测试
  • vb+access库存管理系统设计与实现
  • 机器学习03-数据理解(小白快速理解分析Pima Indians数据集)
  • Hadoop生态体系-HDFS
  • 《实战AI模型》——赶上GPT3.5的大模型LLaMA 2可免费商用,内含中文模型推理和微调解决方案
  • 工程安全监测无线振弦采集仪在建筑物的应用分析
  • OpenCV实现照片换底色处理
  • 安科瑞智能型BA系列电流传感器
  • Windows SMB 共享文件夹 排错指南
  • nestjs+typeorm+mysql基本使用学习
  • echarts柱状图每根柱子添加警戒值/阈值,分段警戒线
  • 边缘提取总结
  • intellij 编辑器内性能提示
  • 手机python怎么用海龟画图,python怎么在手机上编程
  • 谈谈你对Synchronized关键字的理解及使用
  • 移动硬盘文件或目录损坏且无法读取
  • MySQL - 常用的命令
  • 【代理模式】了解篇:静态代理 动态代理~
  • LLM 大语言模型 Prompt Technique 论文精读-3
  • 架构重构实践心得
  • 【配置环境】Windows下 VS Code 远程连接虚拟机Ubuntu
  • 【设计模式——学习笔记】23种设计模式——组合模式Composite(原理讲解+应用场景介绍+案例介绍+Java代码实现)
  • vue3+Luckysheet实现表格的在线预览编辑(electron可用)
  • 前端html中让两个或者多个div在一行显示,用style给div加上css样式
  • 【linux基础(二)】Linux基本指令(中)