[sheepdog] [PATCH v2 01/11] rbtree: make rb_for_each_entry and rb_for_each more generic
MORITA Kazutaka
morita.kazutaka at gmail.com
Wed Sep 18 19:35:35 CEST 2013
At Sat, 14 Sep 2013 18:34:21 +0800,
Liu Yuan wrote:
>
> This allows us to call rb_xxx helpers inside the rb_for_xx helpers.
>
> Signed-off-by: Liu Yuan <namei.unix at gmail.com>
> ---
> include/rbtree.h | 12 ++++++------
> 1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/include/rbtree.h b/include/rbtree.h
> index 92c5389..07b6fe6 100644
> --- a/include/rbtree.h
> +++ b/include/rbtree.h
> @@ -164,16 +164,16 @@ static inline void rb_link_node(struct rb_node *node, struct rb_node *parent,
> /* Iterate over a rbtree safe against removal of rbnode */
> #define rb_for_each(pos, root) \
> pos = rb_first(root); \
> - for (struct rb_node *__n = rb_next(pos); \
> - pos && ({ __n = rb_next(pos); 1; }); \
> - pos = __n)
> + for (struct rb_node *__n1 = rb_next(pos); \
> + pos && ({ __n1 = rb_next(pos); 1; }); \
> + pos = __n1)
>
> /* Iterate over a rbtree of given type safe against removal of rbnode */
> #define rb_for_each_entry(pos, root, member) \
> - for (struct rb_node *__pos = rb_first(root), *__n; \
> - __pos && ({ __n = rb_next(__pos); 1; }) && \
> + for (struct rb_node *__pos = rb_first(root), *__n2; \
> + __pos && ({ __n2 = rb_next(__pos); 1; }) && \
> ({ pos = rb_entry(__pos, typeof(*pos), member); 1; }); \
> - __pos = __n)
> + __pos = __n2)
Then, we have to introduce __n3, __n4, ... to call macros inside
rb_for_each_entry()? I think we should use better name convention.
E.g. adding a prefix like "__rb_for_each_entry_n" is unlikely to cause
collision though it's a bit too long.
I'd suggest adding a line number to the variable. The below macro
generates a dynamic variable name with a line number.
#define __LOCAL(var, line) __ ## var ## line
#define _LOCAL(var, line) __LOCAL(var, line)
#define LOCAL(var) _LOCAL(var, __LINE__)
Then rb_for_each_entry() would be as follows.
for (struct rb_node *LOCAL(pos) = rb_first(root), *LOCAL(n); \
LOCAL(pos) && ({ LOCAL(n) = rb_next(LOCAL(pos)); 1; }) && \
({ pos = rb_entry(LOCAL(pos), typeof(*pos), member); 1; }); \
LOCAL(pos) = LOCAL(n))
This also allows us to use rb_for_each_entry() inside rb_for_each_entry().
Thanks,
Kazutaka
More information about the sheepdog
mailing list