Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / tools / perf / util / intlist.c
diff --git a/kernel/tools/perf/util/intlist.c b/kernel/tools/perf/util/intlist.c
new file mode 100644 (file)
index 0000000..89715b6
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Based on intlist.c by:
+ * (c) 2009 Arnaldo Carvalho de Melo <acme@redhat.com>
+ *
+ * Licensed under the GPLv2.
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <linux/compiler.h>
+
+#include "intlist.h"
+
+static struct rb_node *intlist__node_new(struct rblist *rblist __maybe_unused,
+                                        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;
+               node->priv = NULL;
+               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 __maybe_unused,
+                                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, struct int_node *node)
+{
+       rblist__remove_node(&ilist->rblist, &node->rb_node);
+}
+
+static struct int_node *__intlist__findnew(struct intlist *ilist,
+                                          int i, bool create)
+{
+       struct int_node *node = NULL;
+       struct rb_node *rb_node;
+
+       if (ilist == NULL)
+               return NULL;
+
+       if (create)
+               rb_node = rblist__findnew(&ilist->rblist, (void *)((long)i));
+       else
+               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 int_node *intlist__find(struct intlist *ilist, int i)
+{
+       return __intlist__findnew(ilist, i, false);
+}
+
+struct int_node *intlist__findnew(struct intlist *ilist, int i)
+{
+       return __intlist__findnew(ilist, i, true);
+}
+
+static int intlist__parse_list(struct intlist *ilist, const char *s)
+{
+       char *sep;
+       int err;
+
+       do {
+               long value = strtol(s, &sep, 10);
+               err = -EINVAL;
+               if (*sep != ',' && *sep != '\0')
+                       break;
+               err = intlist__add(ilist, value);
+               if (err)
+                       break;
+               s = sep + 1;
+       } while (*sep != '\0');
+
+       return err;
+}
+
+struct intlist *intlist__new(const char *slist)
+{
+       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;
+
+               if (slist && intlist__parse_list(ilist, slist))
+                       goto out_delete;
+       }
+
+       return ilist;
+out_delete:
+       intlist__delete(ilist);
+       return NULL;
+}
+
+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;
+}