The container_of() function in Kernel:
It is a macro, used to find the starting address of the structure by using its own member variables. We use this macro to retrieve the structure given the details of the pointer points to one of its member variables.
It accepts three arguments and returns start of address of the required structure type specified in the argument list.
Its definition is
#define container_of (ptr, type, member) ({ \
const typeof( ((type *)0)->member) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type, member) );})
Arguments:
Below example would help us to understand the usage of this macro.
struct my_container {
int some_data;
/*
* members list
*/
int some_other_data;
}
Now, we have function1(), where this structure is used like below.
function1() {
/* other_code */
int *new_ptr_data = my_container_ptr->some_other_data;
function2(new_ptr);
/* other code */
}
And, we are passing new_ptr variable to another function2(new_ptr).
In the function2(), we need to access the other members of the structure of type struct my_container. But, we should not pass this structure in the argument list of function2().
So, the use of container_of macro comes into the picture now.
In function2(), we can retrieve the structure by using container_of macro like below.
function2(int *new_ptr){
struct my_container *my_container_ptr =
container_of(new_ptr, struct my_container, some_other_data);
/*
* use my_container_ptr to access the members
*/
/* other_code */
}
If you see the argument list of container_of macro, found the 3rd argument is some_other_data, since the new_ptr is pointed to this member only. So, we should specify this member as 3rd argument.
If the new_ptr is pointed to some_other_data2 (for example) then we should specify 3rd argument as some_other_data2 only.
It is a macro, used to find the starting address of the structure by using its own member variables. We use this macro to retrieve the structure given the details of the pointer points to one of its member variables.
It accepts three arguments and returns start of address of the required structure type specified in the argument list.
Its definition is
#define container_of (ptr, type, member) ({ \
const typeof( ((type *)0)->member) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type, member) );})
Arguments:
- ptr: refers to the name of the pointer
- type: structure name & type
- member: refers to the name of the structure member
Below example would help us to understand the usage of this macro.
struct my_container {
int some_data;
/*
* members list
*/
int some_other_data;
}
Now, we have function1(), where this structure is used like below.
function1() {
/* other_code */
int *new_ptr_data = my_container_ptr->some_other_data;
function2(new_ptr);
/* other code */
}
And, we are passing new_ptr variable to another function2(new_ptr).
In the function2(), we need to access the other members of the structure of type struct my_container. But, we should not pass this structure in the argument list of function2().
So, the use of container_of macro comes into the picture now.
In function2(), we can retrieve the structure by using container_of macro like below.
function2(int *new_ptr){
struct my_container *my_container_ptr =
container_of(new_ptr, struct my_container, some_other_data);
/*
* use my_container_ptr to access the members
*/
/* other_code */
}
If you see the argument list of container_of macro, found the 3rd argument is some_other_data, since the new_ptr is pointed to this member only. So, we should specify this member as 3rd argument.
If the new_ptr is pointed to some_other_data2 (for example) then we should specify 3rd argument as some_other_data2 only.
No comments:
Post a Comment