Rename __member2struct() to __containerof().
Compared to __member2struct(), this macro has the following advantages: - It ensures that the type of the pointer is compatible with the member field of the structure (or a void pointer). - It works properly in combination with volatile and const, though unfortunately it drops these qualifiers from the returned value. mdf@ proposed to add the container_of() macro, just like Linux has. Eventually I decided against this, as <sys/param.h> is included all over the place. It seems container_of() on Linux is specific to the kernel, not userspace. I'd rather not pollute userspace with this. I also thought about adding __container_of(), but this would have two advantages. Xorg seems to already have a __container_of(), which is not compatible with this version. Also, the underscore in the middle conflicts with our existing macros (__offsetof, __rangeof, etc). I'm changing member2struct() to use its old code, as the extra strictness of this new macro conflicts with existing code (read: cxgb). MFC after: 1 month
This commit is contained in:
parent
03a51ef8f4
commit
5b5d76847d
@ -402,8 +402,22 @@
|
||||
#endif
|
||||
#define __rangeof(type, start, end) \
|
||||
(__offsetof(type, end) - __offsetof(type, start))
|
||||
#define __member2struct(s, m, x) \
|
||||
((struct s *)(void *)((char *)(x) - __offsetof(struct s, m)))
|
||||
|
||||
/*
|
||||
* Given the pointer x to the member m of the struct s, return
|
||||
* a pointer to the containing structure. When using GCC, we first
|
||||
* assign pointer x to a local variable, to check that its type is
|
||||
* compatible with member m.
|
||||
*/
|
||||
#if __GNUC_PREREQ__(3, 1)
|
||||
#define __containerof(x, s, m) ({ \
|
||||
const volatile __typeof(((s *)0)->m) *__x = (x); \
|
||||
__DEQUALIFY(s *, (const volatile char *)__x - __offsetof(s, m));\
|
||||
})
|
||||
#else
|
||||
#define __containerof(x, s, m) \
|
||||
__DEQUALIFY(s *, (const volatile char *)(x) - __offsetof(s, m))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Compiler-dependent macros to declare that functions take printf-like
|
||||
|
@ -331,10 +331,10 @@ __END_DECLS
|
||||
((db) << (PAGE_SHIFT - DEV_BSHIFT))
|
||||
|
||||
/*
|
||||
* Given the pointer x to the member m of the struct s, return
|
||||
* a pointer to the containing structure.
|
||||
* Old spelling of __containerof().
|
||||
*/
|
||||
#define member2struct(s, m, x) __member2struct(s, m, x)
|
||||
#define member2struct(s, m, x) \
|
||||
((struct s *)(void *)((char *)(x) - offsetof(struct s, m)))
|
||||
|
||||
/*
|
||||
* Access a variable length array that has been declared as a fixed
|
||||
|
@ -287,9 +287,8 @@ struct { \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_LAST(head, type, field) \
|
||||
(STAILQ_EMPTY((head)) ? \
|
||||
NULL : \
|
||||
__member2struct(type, field.stqe_next, (head)->stqh_last))
|
||||
(STAILQ_EMPTY((head)) ? NULL : \
|
||||
__containerof((head)->stqh_last, struct type, field.stqe_next))
|
||||
|
||||
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
|
||||
|
||||
@ -425,9 +424,8 @@ struct { \
|
||||
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
|
||||
|
||||
#define LIST_PREV(elm, head, type, field) \
|
||||
((elm)->field.le_prev == &LIST_FIRST((head)) ? \
|
||||
NULL : \
|
||||
__member2struct(type, field.le_next, (elm)->field.le_prev))
|
||||
((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL : \
|
||||
__containerof((elm)->field.le_prev, struct type, field.le_next))
|
||||
|
||||
#define LIST_REMOVE(elm, field) do { \
|
||||
QMD_SAVELINK(oldnext, (elm)->field.le_next); \
|
||||
|
Loading…
x
Reference in New Issue
Block a user