Linked List In Kernel
Canonical list
struct point2DNode{
int x,y;
struct point2DNode* prev, next;
};
The drawback of this approach is that in order to manipulate that list one have to write type specific code for adding/removing nodes in/from the list.
struct list_head is defined as follow :
struct list_head{
struct list_head *next, *prev;
};
#define LIST_HEAD(name) \
struct list_head name =LIST_HEAD_INIT(name)
#define LIST_HEAD_INIT(name) { &(name), &(name) }
With that in mind our kernel point2D list would be
struct point2D{
int x,y;
struct list_head list;
};
Iterate over the list
/**
* list_for_each-iterate over a list
* @pos:the &struct list_head to use as a loop counter.
* @head:the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
But as you may have noticed the loop is now over the struct list_head so, how can one retrieve the embedding structure (a some point we would like to access linked lists’ node fields). Using the list_entry function provided is the answer.
/**
* list_entry - get the struct for this entry
* @ptr:the &struct list_head pointer.
* @type:the type of the struct this is embedded in.
* @member:the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member) \
( (type *)( (char *)(ptr)-(unsigned long)(&( (type *) 0 )->member) ) )
Here an example of usage.
struct list_head* current;
struct point2D* currPoint;
//prints out all the points2D currently in the list
list_for_each(current, &listStart){
currPoint = list_entry(current,struct point2D,list);
printf("x=%d, y=%d\n",currPoint->x,currPoint->y);
}
Written on April 13, 2018