From 70b40c4a43ddfcf7a06dad4be32ff1dd2b62be09 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Mon, 30 Jul 2012 22:31:34 -0600 Subject: [PATCH] perf tools: Introduce intlist Built on rblist - like strlist. Used in the next patch. Signed-off-by: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1343709095-7089-4-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 2 + tools/perf/util/intlist.c | 101 ++++++++++++++++++++++++++++++++++++++ tools/perf/util/intlist.h | 75 ++++++++++++++++++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 tools/perf/util/intlist.c create mode 100644 tools/perf/util/intlist.h diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 285f700a7836..32912af430f0 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -320,6 +320,7 @@ LIB_H += util/cgroup.h LIB_H += $(TRACE_EVENT_DIR)event-parse.h LIB_H += util/target.h LIB_H += util/rblist.h +LIB_H += util/intlist.h LIB_OBJS += $(OUTPUT)util/abspath.o LIB_OBJS += $(OUTPUT)util/alias.o @@ -385,6 +386,7 @@ LIB_OBJS += $(OUTPUT)util/cpumap.o LIB_OBJS += $(OUTPUT)util/cgroup.o LIB_OBJS += $(OUTPUT)util/target.o LIB_OBJS += $(OUTPUT)util/rblist.o +LIB_OBJS += $(OUTPUT)util/intlist.o BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o diff --git a/tools/perf/util/intlist.c b/tools/perf/util/intlist.c new file mode 100644 index 000000000000..fd530dced9cb --- /dev/null +++ b/tools/perf/util/intlist.c @@ -0,0 +1,101 @@ +/* + * Based on intlist.c by: + * (c) 2009 Arnaldo Carvalho de Melo + * + * Licensed under the GPLv2. + */ + +#include +#include +#include + +#include "intlist.h" + +static struct rb_node *intlist__node_new(struct rblist *rblist __used, + const void *entry) +{ + int i = (int)((long)entry); + struct rb_node *rc = NULL; + struct int_node *node = malloc(sizeof(*node)); + + if (node != NULL) { + node->i = i; + rc = &node->rb_node; + } + + return rc; +} + +static void int_node__delete(struct int_node *ilist) +{ + free(ilist); +} + +static void intlist__node_delete(struct rblist *rblist __used, + struct rb_node *rb_node) +{ + struct int_node *node = container_of(rb_node, struct int_node, rb_node); + + int_node__delete(node); +} + +static int intlist__node_cmp(struct rb_node *rb_node, const void *entry) +{ + int i = (int)((long)entry); + struct int_node *node = container_of(rb_node, struct int_node, rb_node); + + return node->i - i; +} + +int intlist__add(struct intlist *ilist, int i) +{ + return rblist__add_node(&ilist->rblist, (void *)((long)i)); +} + +void intlist__remove(struct intlist *ilist __used, struct int_node *node) +{ + int_node__delete(node); +} + +struct int_node *intlist__find(struct intlist *ilist, int i) +{ + struct int_node *node = NULL; + struct rb_node *rb_node = rblist__find(&ilist->rblist, (void *)((long)i)); + + if (rb_node) + node = container_of(rb_node, struct int_node, rb_node); + + return node; +} + +struct intlist *intlist__new(void) +{ + struct intlist *ilist = malloc(sizeof(*ilist)); + + if (ilist != NULL) { + rblist__init(&ilist->rblist); + ilist->rblist.node_cmp = intlist__node_cmp; + ilist->rblist.node_new = intlist__node_new; + ilist->rblist.node_delete = intlist__node_delete; + } + + return ilist; +} + +void intlist__delete(struct intlist *ilist) +{ + if (ilist != NULL) + rblist__delete(&ilist->rblist); +} + +struct int_node *intlist__entry(const struct intlist *ilist, unsigned int idx) +{ + struct int_node *node = NULL; + struct rb_node *rb_node; + + rb_node = rblist__entry(&ilist->rblist, idx); + if (rb_node) + node = container_of(rb_node, struct int_node, rb_node); + + return node; +} diff --git a/tools/perf/util/intlist.h b/tools/perf/util/intlist.h new file mode 100644 index 000000000000..6d63ab90db50 --- /dev/null +++ b/tools/perf/util/intlist.h @@ -0,0 +1,75 @@ +#ifndef __PERF_INTLIST_H +#define __PERF_INTLIST_H + +#include +#include + +#include "rblist.h" + +struct int_node { + struct rb_node rb_node; + int i; +}; + +struct intlist { + struct rblist rblist; +}; + +struct intlist *intlist__new(void); +void intlist__delete(struct intlist *ilist); + +void intlist__remove(struct intlist *ilist, struct int_node *in); +int intlist__add(struct intlist *ilist, int i); + +struct int_node *intlist__entry(const struct intlist *ilist, unsigned int idx); +struct int_node *intlist__find(struct intlist *ilist, int i); + +static inline bool intlist__has_entry(struct intlist *ilist, int i) +{ + return intlist__find(ilist, i) != NULL; +} + +static inline bool intlist__empty(const struct intlist *ilist) +{ + return rblist__empty(&ilist->rblist); +} + +static inline unsigned int intlist__nr_entries(const struct intlist *ilist) +{ + return rblist__nr_entries(&ilist->rblist); +} + +/* For intlist iteration */ +static inline struct int_node *intlist__first(struct intlist *ilist) +{ + struct rb_node *rn = rb_first(&ilist->rblist.entries); + return rn ? rb_entry(rn, struct int_node, rb_node) : NULL; +} +static inline struct int_node *intlist__next(struct int_node *in) +{ + struct rb_node *rn; + if (!in) + return NULL; + rn = rb_next(&in->rb_node); + return rn ? rb_entry(rn, struct int_node, rb_node) : NULL; +} + +/** + * intlist_for_each - iterate over a intlist + * @pos: the &struct int_node to use as a loop cursor. + * @ilist: the &struct intlist for loop. + */ +#define intlist__for_each(pos, ilist) \ + for (pos = intlist__first(ilist); pos; pos = intlist__next(pos)) + +/** + * intlist_for_each_safe - iterate over a intlist safe against removal of + * int_node + * @pos: the &struct int_node to use as a loop cursor. + * @n: another &struct int_node to use as temporary storage. + * @ilist: the &struct intlist for loop. + */ +#define intlist__for_each_safe(pos, n, ilist) \ + for (pos = intlist__first(ilist), n = intlist__next(pos); pos;\ + pos = n, n = intlist__next(n)) +#endif /* __PERF_INTLIST_H */