美文网首页
Linux kernel 数据结构 hlist (3)

Linux kernel 数据结构 hlist (3)

作者: _invincible_ | 来源:发表于2021-02-07 11:27 被阅读0次
  • 前情提要
    上文 给了一个打印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 <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/hashtable.h>
#include <linux/vmalloc.h>

#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

相关文章

网友评论

      本文标题:Linux kernel 数据结构 hlist (3)

      本文链接:https://www.haomeiwen.com/subject/ekdnzktx.html