内核中的list_head连接件使用备忘。
从链表头、链表尾插入节点,从头到尾遍历结点,从尾到头遍历结点,删除节点,遍历并立即删除节点,判断节点是否空。
系统环境:ubuntu-10.04/linux-2.6.32-38-generic/gcc version 4.3.4(Ubuntu 4.3.4 10ubuntu1)
代码:
myklist.c
- #include <linux/init.h>
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/string.h>
- #include <linux/list.h>
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("zl");
- MODULE_DESCRIPTION("klist test");
- struct list_head klisthead;
- struct mytype {
- char *keystring;
- struct list_head knode;
- };
- typedef int (*cmp_t)(void *arg1, void *arg2);
- char *array[] = {
- "aaaaa",
- "bbb",
- "333",
- "c",
- "dddd",
- "111",
- "eeeeeeeee",
- "ffffghi",
- "222",
- "gggabcd",
- "13579"
- "abcdefg"
- };
- #define TAB_SIZE(array) (sizeof(array)/sizeof(array[0]))
- static int __init klist_init(void)
- {
- int i;
- struct mytype *node;
- struct list_head *tmp;
- struct list_head *pos;
- INIT_LIST_HEAD(&klisthead);
- /** first time list_add/list_del/list_for_each/list_for_each_safe **/
- printk("\n********list_add*************************************\n");
- if(list_empty(&klisthead))
- {
- printk("[%s-%d]: The list have no node !\n", __func__, __LINE__);
- }
- printk("----------list_for_each------------------------------\n");
- for(i = 0; i < TAB_SIZE(array); i++)
- {
- node = kzalloc(sizeof(struct mytype), GFP_KERNEL);
- if(node == NULL)
- {
- printk("[%s-%d]kzalloc failed !\n", __func__, __LINE__);
- goto err1;
- }
- node->keystring = array[i];
- list_add(&(node->knode), &klisthead);
- }
-
- if(!list_empty(&klisthead))
- {
- printk("[%s-%d]: The list have some node !\n", __func__, __LINE__);
- }
- i = 0;
- list_for_each(pos, &klisthead)
- {
- node = list_entry(pos, struct mytype, knode);
- printk("i = %d, keystring = %s \n", i, node->keystring);
- i++;
- }
- printk("\n----------list_for_each_safe/list_del----------------\n");
- i = 0;
- list_for_each_safe(pos, tmp, &klisthead)
- {
- node = list_entry(pos, struct mytype, knode);
- printk("i = %d, keystring = %s \n", i, node->keystring);
- i++;
- list_del(&(node->knode));
- kfree(node);
- }
- if(list_empty(&klisthead))
- {
- printk("[%s-%d]: The list have no node !\n", __func__, __LINE__);
- }
- /** second time list_add_tail/list_del_init/list_for_each_prev/list_for_each_prev_safe**/
- printk("\n********list_add_tail********************************\n");
- printk("----------list_for_each------------------------------\n");
- for(i = 0; i < TAB_SIZE(array); i++)
- {
- node = kzalloc(sizeof(struct mytype), GFP_KERNEL);
- if(node == NULL)
- {
- printk("[%s-%d]kzalloc failed !\n", __func__, __LINE__);
- goto err1;
- }
- node->keystring = array[i];
- //list_add(&(node->knode), &klisthead);
- list_add_tail(&(node->knode), &klisthead);
- }
- if(!list_empty(&klisthead))
- {
- printk("[%s-%d]: The list have some node !\n", __func__, __LINE__);
- }
- i = 0;
- list_for_each(pos, &klisthead)
- {
- node = list_entry(pos, struct mytype, knode);
- printk("i = %d, keystring = %s \n", i, node->keystring);
- i++;
- }
- printk("----------list_for_each_prev-------------------------\n");
- i = 0;
- list_for_each_prev(pos, &klisthead)
- {
- node = list_entry(pos, struct mytype, knode);
- printk("i = %d, keystring = %s \n", i, node->keystring);
- i++;
- }
- printk("----------list_for_each_prev_safe/list_del_init------\n");
- i = 0;
- list_for_each_prev_safe(pos, tmp, &klisthead)
- {
- node = list_entry(pos, struct mytype, knode);
- printk("i = %d, keystring = %s \n", i, node->keystring);
- i++;
- list_del_init(&(node->knode));
- kfree(node);
- }
- if(list_empty(&klisthead))
- {
- printk("[%s-%d]: The list have no node !\n", __func__, __LINE__);
- }
- return 0;
- err1:
- return -1;
- }
- static void __exit klist_exit(void)
- {
- printk("exit !\n");
- }
- module_init(klist_init);
- module_exit(klist_exit);
makefile文件
- obj-m = myklist.o
- #KERNELS = /home/zl/linux-2.6.30.4
- #KERNELS = /media/STUDY/linux/kernel/my2440-2.6.36
- KERNELS = /lib/modules/$(shell uname -r)/build/
- default:
- make -C $(KERNELS) M=$(shell pwd) modules
- .PHONY:clean
- clean:
- make -C $(KERNELS) M=$(shell pwd) clean
编译,运行,及查看运行结果:符合预期