/*
* Macro used to acces an element in a list.
* Type casting a '0' to type* then accessing its member....?
*/
//this is a common trick for calculating the offset of a member in a
//struct. The offsetof() macro works this way too.
#define list_entry(ptr, type, member) \
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
//you cheat the compiler, telling it to treat a NULL pointer as a pointer
//to the struct. Then you try to access a member of through that pointer
//and store its address. Because the we used NULL, the result is the
//number of bytes between the struct's beginning and the member's address.
//This whole story is expressed in this expression: &((type *)0)->member))
//Now since we got the offset of a specific member in a struct, we need to
//subtract it from the enclosing struct to get that enclosing struct's
//address: (char *)(ptr)-(unsigned long). Finally, we cast the result to
//the desired type.
/*
* Example of its use
*/
struct super_block {
...
struct list_head s_files;
...
} *sb = &some_super_block;
struct file {
...
struct list_head f_list;
...
} *file;
struct list_head *p;
for (p = sb->s_files.next; p != &sb->s_files; p = p->next) {
struct file *file = list_entry(p, struct file, f_list);
do something to 'file'
}
a linux kernel macro
Mar032009
Subscribe to:
Post Comments (Atom)
0 评论: (+add yours?)
Post a Comment