Skip to content

Commit

Permalink
perf tools: Introducing rblist
Browse files Browse the repository at this point in the history
rblist is the rbtree based code from strlist. It will be the common code
for strlist and the to-be-introduced intlist.

Signed-off-by: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
  • Loading branch information
dsahern authored and acmel committed Aug 3, 2012
1 parent 347ed99 commit 37bbd3f
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 0 deletions.
2 changes: 2 additions & 0 deletions tools/perf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ LIB_H += $(ARCH_INCLUDE)
LIB_H += util/cgroup.h
LIB_H += $(TRACE_EVENT_DIR)event-parse.h
LIB_H += util/target.h
LIB_H += util/rblist.h

LIB_OBJS += $(OUTPUT)util/abspath.o
LIB_OBJS += $(OUTPUT)util/alias.o
Expand Down Expand Up @@ -383,6 +384,7 @@ LIB_OBJS += $(OUTPUT)util/xyarray.o
LIB_OBJS += $(OUTPUT)util/cpumap.o
LIB_OBJS += $(OUTPUT)util/cgroup.o
LIB_OBJS += $(OUTPUT)util/target.o
LIB_OBJS += $(OUTPUT)util/rblist.o

BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o

Expand Down
107 changes: 107 additions & 0 deletions tools/perf/util/rblist.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Based on strlist.c by:
* (c) 2009 Arnaldo Carvalho de Melo <[email protected]>
*
* Licensed under the GPLv2.
*/

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

#include "rblist.h"

int rblist__add_node(struct rblist *rblist, const void *new_entry)
{
struct rb_node **p = &rblist->entries.rb_node;
struct rb_node *parent = NULL, *new_node;

while (*p != NULL) {
int rc;

parent = *p;

rc = rblist->node_cmp(parent, new_entry);
if (rc > 0)
p = &(*p)->rb_left;
else if (rc < 0)
p = &(*p)->rb_right;
else
return -EEXIST;
}

new_node = rblist->node_new(rblist, new_entry);
if (new_node == NULL)
return -ENOMEM;

rb_link_node(new_node, parent, p);
rb_insert_color(new_node, &rblist->entries);
++rblist->nr_entries;

return 0;
}

void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node)
{
rb_erase(rb_node, &rblist->entries);
rblist->node_delete(rblist, rb_node);
}

struct rb_node *rblist__find(struct rblist *rblist, const void *entry)
{
struct rb_node **p = &rblist->entries.rb_node;
struct rb_node *parent = NULL;

while (*p != NULL) {
int rc;

parent = *p;

rc = rblist->node_cmp(parent, entry);
if (rc > 0)
p = &(*p)->rb_left;
else if (rc < 0)
p = &(*p)->rb_right;
else
return parent;
}

return NULL;
}

void rblist__init(struct rblist *rblist)
{
if (rblist != NULL) {
rblist->entries = RB_ROOT;
rblist->nr_entries = 0;
}

return;
}

void rblist__delete(struct rblist *rblist)
{
if (rblist != NULL) {
struct rb_node *pos, *next = rb_first(&rblist->entries);

while (next) {
pos = next;
next = rb_next(pos);
rb_erase(pos, &rblist->entries);
rblist->node_delete(rblist, pos);
}
free(rblist);
}
}

struct rb_node *rblist__entry(const struct rblist *rblist, unsigned int idx)
{
struct rb_node *node;

for (node = rb_first(&rblist->entries); node; node = rb_next(node)) {
if (!idx--)
return node;
}

return NULL;
}
47 changes: 47 additions & 0 deletions tools/perf/util/rblist.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#ifndef __PERF_RBLIST_H
#define __PERF_RBLIST_H

#include <linux/rbtree.h>
#include <stdbool.h>

/*
* create node structs of the form:
* struct my_node {
* struct rb_node rb_node;
* ... my data ...
* };
*
* create list structs of the form:
* struct mylist {
* struct rblist rblist;
* ... my data ...
* };
*/

struct rblist {
struct rb_root entries;
unsigned int nr_entries;

int (*node_cmp)(struct rb_node *rbn, const void *entry);
struct rb_node *(*node_new)(struct rblist *rlist, const void *new_entry);
void (*node_delete)(struct rblist *rblist, struct rb_node *rb_node);
};

void rblist__init(struct rblist *rblist);
void rblist__delete(struct rblist *rblist);
int rblist__add_node(struct rblist *rblist, const void *new_entry);
void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node);
struct rb_node *rblist__find(struct rblist *rblist, const void *entry);
struct rb_node *rblist__entry(const struct rblist *rblist, unsigned int idx);

static inline bool rblist__empty(const struct rblist *rblist)
{
return rblist->nr_entries == 0;
}

static inline unsigned int rblist__nr_entries(const struct rblist *rblist)
{
return rblist->nr_entries;
}

#endif /* __PERF_RBLIST_H */

0 comments on commit 37bbd3f

Please sign in to comment.