Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

list_entry in Linux

user/include/linux/list.h 

this declaration:

#define list_entry(ptr, type, member) \ ((type *)((char *)(ptr) – (unsigned long)(&((type *)0)->member))) 

can somebody please explain what is this and how does it work, thanks in advance

P.S. please simplify your answer as much as possible, I know about threads, processes in Linux, now I'm exploring possibilities and I'm a little bit stuck with this one.

like image 981
likeIT Avatar asked Apr 05 '11 10:04

likeIT


People also ask

What is List_entry Linux?

The list_entry() macro helps you to convert data_ptr to a pointer to the struct container value that holds the struct data value, pointed to by ptr : struct container *cont_ptr = list_entry(data_ptr, struct container, data_item);

What is List_for_each?

The simplest way to iterate over a list is with the list_for_each() macro. The macro takes two parameters, both list_head structures. The first is a pointer used to point to the current entry; it is a temporary variable that you must provide. The second is a list_head in the list you want to traverse.

What is list_head in Linux kernel?

The 'list.h' kernel header file defines the -only- acceptable linked list implementation for the Linux kernel (as per kernel.org folks). In tern, 'list.h' includes 'types.h', which define the following: struct list_head { struct list_head *next, *prev; }

What is Container_of?

container_of(ptr, type, member) member – the name of the member within the struct. It returns the address of the container structure of the member.


1 Answers

Consider two structs like this:

struct data {     int something; };  struct container {     int something_before;     struct data data_item;     int something_after; }; 

Assume you have a pointer to a struct data value:

struct data *data_ptr; 

The list_entry() macro helps you to convert data_ptr to a pointer to the struct container value that holds the struct data value, pointed to by ptr:

struct container *cont_ptr = list_entry(data_ptr, struct container, data_item); 

The macro works by computing the offset of data_item inside the struct container, and subtracting that many bytes from the data_ptr pointer. This, when cast to struct container *, gives a valid pointer to the struct container that holds this particular struct data "inside".

The macro can also be simplified a bit by using the builtin offsetof() macro:

#define list_entry(ptr, type, member) \     ((type *)((char *)(ptr) – offsetof(type, member))) 
like image 183
Petri Lehtinen Avatar answered Sep 24 '22 22:09

Petri Lehtinen