linux hlist,Linux kernel 数据结构 hlist (3)

前情提要

上文 给了一个打印hlist的demo,遍历函数是自己随便实现的,本文会给出一个使用正经的Linux kernel API来遍历的例子

API

/**

* hash_for_each - iterate over a hashtable

* @name: hashtable to iterate

* @bkt: integer to use as bucket loop cursor

* @obj: the type * to use as a loop cursor for each entry

* @member: the name of the hlist_node within the struct

*/

#define hash_for_each(name, bkt, obj, member) \

for ((bkt) = 0, obj = NULL; obj == NULL && (bkt) < HASH_SIZE(name);\

(bkt)++)\

hlist_for_each_entry(obj, &name[bkt], member)

/**

* hlist_for_each_entry - iterate over list of given type

* @pos: the type * to use as a loop cursor.

* @head: the head for your list.

* @member: the name of the hlist_node within the struct.

*/

#define hlist_for_each_entry(pos, head, member) \

for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\

pos; \

pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))

#define hlist_entry_safe(ptr, type, member) \

({ typeof(ptr) ____ptr = (ptr); \

____ptr ? hlist_entry(____ptr, type, member) : NULL; \

})

code

#include

#include

#include

#include

#include

#define HBITS 2

DEFINE_HASHTABLE(planet_htable, HBITS);

struct planet {

int mass;

char name[16];

struct hlist_node node;

};

struct planet *create_planet(int mass, char *name);

void destroy_planet(struct planet *p);

void hlist_print(void);

void hlist_test(void);

void create_planet(int mass, char *name){

struct planet *p;

p = vmalloc(sizeof(struct planet));

if(!p){

pr_err("[!] Create planet failed.\n");

return NULL;

}

memset(p, 0, sizeof(struct planet));

p->mass = mass;

strcpy(p->name, name);

hash_add_rcu(planet_htable, &p->node, p->mass);

return p;

}

void destroy_planet(struct planet *p){

hash_del_rcu(&p->node);

vfree(p);

}

void hlist_print(void){

struct planet *p;

int i = 0;

hash_for_each_rcu(planet_htable, i, p, node){

pr_info("i: %d, p: %px, p->name: %s\n", i, p, p->name);

}

}

void hlist_test(void){

struct planet * earth;

struct planet * mars;

struct planet * venus;

struct planet * jupiter;

earth = create_planet(0, "Earth");

mars = create_planet(1, "Mars ");

venus = create_planet(1, "Venus");

jupiter = create_planet(1, "Jupiter");

hlist_print();

destroy_planet(earth);

destroy_planet(mars);

destroy_planet(venus);

destroy_planet(jupiter);

}

static int __init hlist_t_init(void)

{

printk(KERN_INFO "Hello hlist_t\n");

hlist_test();

return 0;

}

static void __exit hlist_t_exit(void)

{

printk(KERN_INFO "Goodbye hlist_t\n");

}

module_init(hlist_t_init);

module_exit(hlist_t_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("X++0");

MODULE_DESCRIPTION("Kernel xxx Module.");

MODULE_VERSION("0.1");

output

[10447.917434] Earth, 0 created

[10447.918381] Mars , 1 created

[10447.919051] Venus, 1 created

[10447.919860] Jupiter, 1 created

[10447.920673] i: 0, p: ffffc9000009f000, p->name: Earth

[10447.921676] i: 1, p: ffffc900000fb000, p->name: Jupiter

[10447.922523] i: 1, p: ffffc900000a3000, p->name: Venus

[10447.923336] i: 1, p: ffffc900000a1000, p->name: Mars

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值