

List_for_each ( position, & mylinkedlist )ĭatastructureptr = list_entry ( position, struct mystruct, mylist ) Struct mystruct *datastructureptr = NULL We can now write a loop which will display to the console the contents of the data fields of our linked list elements:
Listhead linux kernel example code#
Once this computation is done the container_of macro simply expands to its results as it is composed of 2 lines of code between parenthesis.

To obtain an offset, we take the address of that MEMBER from a NULL pointer cast into TYPE. This done by using the offsetof macro defined in /include/linux/stddef.h as Ģ0 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)Īs you can see, this macro simply expands to the address of the MEMBER field in the data structure TYPE. The next step is to subtract from the address of ptr (stored in mptr right now) the offset separating the struct list_head field from the beginning of the data structure it is embedded in. We use this pointer to access the field in that data structure which corresponds to our list_head and get its type with the macro typeof to declare a pointer mptr initialised to the value contained in ptr. The first line of the macro casts the value 0 into a pointer of the encapsulating data structure type ( struct task_struct in our example). We have the address of the struct list_head field inside of another data structure (let's say struct task_struct for sake of example). The code above deserves some explanation (Also read FAQ/ContainerOf). The last line is calling a macro LIST_HEAD_INIT which is defined in /include/linux/list.h:ġ9 #define LIST_HEAD_INIT(name) ) Moreover, if you want your data structure to be part of several data structures, adding a few of these fields will work out just fine.īack to our example, let's create our first variable representing an element of our linked-list-soon-to-be:

Here, we can add a struct list_head field to any other data structure and, as we'll see shortly, make it a part of a linked list. The drawback of this approach, and the reason for which the kernel implements linked lists differently, is that you need to write code to handle adding / removing / etc elements specifically for that data structure. When first encountering this, most people are confused because they have been taught to implement linked lists by adding a pointer in a structure which points to the next similar structure in the linked list. To be able to link each element of type struct mystruct to others, we need to add a struct list_head field: Let's start by defining a data structure that we will then embed in a kernel linked list: Let's take a look at the kernel's linked list API from the perspective of "how would I use it in my own code?" (e.g. Understanding this API can help you make sense of tidbits of kernel code here and there but is also a great opportunity to improve your C programming knowledge by reading some very interestingly put together code. Recent versions of the kernel now features a "unified" and very smart generic API to manipulate such data structures. It wasn't uncommon, when working with older versions of the kernel, to encounter redundant code managing classical data structures such as linked lists, hashtables, etc. How does the kernel implements Linked Lists?
