List Handling in Linux Kernel Development

If you want to get a brief information about how to use Linux's linked list data structure, please see the below sample code. You can check-out the code from the github location, build and run on your own Linux development environment.


/*
 * my_object structure.
 */
struct my_object {
        int data;
        struct list_head list;
};

/*
 * list_init()
 */
static int list_init(void)
{
        struct my_object *tmp;
                        /* Temporary object created for each list member */
        struct my_object obj_list;
                        /* List constructed with the tmp objects */
        struct list_head *pos, *n;
                        /* Position pointers in the list */
        int i;

        printk(KERN_INFO "list init\n");

        /*
         * Initialize the list object. This object is used only as the
         * head of the list. It doesn't have any data in it.
         */
        INIT_LIST_HEAD(&obj_list.list);

        for (i = 0; i < 10; i++) {
                tmp = kmalloc(sizeof(struct my_object), GFP_KERNEL);
                if (!tmp) {
                        goto list_cleanup;
                }
                tmp->data = i;
                INIT_LIST_HEAD(&tmp->list);

                /*
                 * Add object to the head of the list.
                 * See list_add_tail() function for adding the object
                 * to the end of the list.
                 */
                list_add(&tmp->list, &obj_list.list);
        }

        /*
         * Traverse the list and print what we have in the list.
         */
        list_for_each(pos, &obj_list.list) {
                tmp = list_entry(pos, struct my_object, list);
                printk(KERN_INFO "%d", tmp->data);

        }

list_cleanup:
        /*
         * We should use list_for_each_safe() function while we are
         * deleting or moving an object from the list.
         */
        list_for_each_safe(pos, n, &obj_list.list) {
                tmp = list_entry(pos, struct my_object, list);
                printk(KERN_INFO "Deleting %d", tmp->data);
                list_del(pos);
                kfree(tmp);
        }
        return 0;
}


OUTPUT:


[25415.787166] list init
[25415.787180] 9
[25415.787185] 8
[25415.787189] 7
[25415.787192] 6
[25415.787195] 5
[25415.787199] 4
[25415.787202] 3
[25415.787206] 2
[25415.787209] 1
[25415.787215] 0
[25415.787219] Deleting 9
[25415.787223] Deleting 8
[25415.787227] Deleting 7
[25415.787231] Deleting 6
[25415.787235] Deleting 5
[25415.787239] Deleting 4
[25415.787242] Deleting 3
[25415.787246] Deleting 2
[25415.787250] Deleting 1
[25415.787254] Deleting 0

Source Code Download:


Comments

Popular posts from this blog

How to Use container_of in Linux Kernel Development

Notification Chains in Linux Kernel

Build and Flash OpenWrt for Raspberry Pi