in linux/include/linux/list.h I found:
/**
* 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_head within the struct.
*/
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
What do they mean by "get the struct for this entry" can I see a usage example to understand in a better way?
This is a great example of a kind of Polymorphism in C. To borrow terminology from C++, the list_entry() macro allows you to downcast from a list_head type to any type that contains it.
Have a look at kthread.c for a simple fundamental example:
kernel/kthread.c:
struct kthread_create_info
{
/* Information passed to kthread() from kthreadd. */
int (*threadfn)(void *data);
void *data;
int node;
/* Result passed back to kthread_create() from kthreadd. */
struct task_struct *result;
struct completion *done;
struct list_head list;
};
...
int kthreadd(void *unused)
{
...
while (!list_empty(&kthread_create_list)) {
struct kthread_create_info *create;
create = list_entry(kthread_create_list.next,
struct kthread_create_info, list);
...
create_kthread(create);
By including a list_head object in the kthread_create_info struct, you can say that kthread_create_info "derives" from list_head. This allows kthread_create_info objects to be used as nodes in a list, meaning you can pass them to any of the functions declared in list.h by simply dereferencing the list member of the struct. The list_entry macro then gives you the mapping from a base class pointer to its derived start address.
In other words, given a list_head object that you know is contained within an outer kthread_create_info struct, you can recover a pointer to the kthread_create_info container.
This is an extremely common pattern in C programming, where object oriented constructs are desired, but a C++ compiler isn't available.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With