--- /dev/null
+#ifndef _PERF_RESORT_RB_H_
+#define _PERF_RESORT_RB_H_
+/*
+ * Template for creating a class to resort an existing rb_tree according to
+ * a new sort criteria, that must be present in the entries of the source
+ * rb_tree.
+ *
+ * (c) 2016 Arnaldo Carvalho de Melo <acme@redhat.com>
+ *
+ * Quick example, resorting threads by its shortname:
+ *
+ * First define the prefix (threads) to be used for the functions and data
+ * structures created, and provide an expression for the sorting, then the
+ * fields to be present in each of the entries in the new, sorted, rb_tree.
+ *
+ * The body of the init function should collect the fields, maybe
+ * pre-calculating them from multiple entries in the original 'entry' from
+ * the rb_tree used as a source for the entries to be sorted:
+
+DEFINE_RB_RESORT_RB(threads, strcmp(a->thread->shortname,
+                                   b->thread->shortname) < 0,
+       struct thread *thread;
+)
+{
+       entry->thread = rb_entry(nd, struct thread, rb_node);
+}
+
+ * After this it is just a matter of instantiating it and iterating it,
+ * for a few data structures with existing rb_trees, such as 'struct machine',
+ * helpers are available to get the rb_root and the nr_entries:
+
+       DECLARE_RESORT_RB_MACHINE_THREADS(threads, machine_ptr);
+
+ * This will instantiate the new rb_tree and a cursor for it, that can be used as:
+
+       struct rb_node *nd;
+
+       resort_rb__for_each(nd, threads) {
+               struct thread *t = threads_entry;
+               printf("%s: %d\n", t->shortname, t->tid);
+       }
+
+ * Then delete it:
+
+       resort_rb__delete(threads);
+
+ * The name of the data structures and functions will have a _sorted suffix
+ * right before the method names, i.e. will look like:
+ *
+ *     struct threads_sorted_entry {}
+ *     threads_sorted__insert()
+ */
+
+#define DEFINE_RESORT_RB(__name, __comp, ...)                                  \
+struct __name##_sorted_entry {                                                 \
+       struct rb_node  rb_node;                                                \
+       __VA_ARGS__                                                             \
+};                                                                             \
+static void __name##_sorted__init_entry(struct rb_node *nd,                    \
+                                       struct __name##_sorted_entry *entry);   \
+                                                                               \
+static int __name##_sorted__cmp(struct rb_node *nda, struct rb_node *ndb)      \
+{                                                                              \
+       struct __name##_sorted_entry *a, *b;                                    \
+       a = rb_entry(nda, struct __name##_sorted_entry, rb_node);               \
+       b = rb_entry(ndb, struct __name##_sorted_entry, rb_node);               \
+       return __comp;                                                          \
+}                                                                              \
+                                                                               \
+struct __name##_sorted {                                                       \
+       struct rb_root              entries;                                    \
+       struct __name##_sorted_entry nd[0];                                     \
+};                                                                             \
+                                                                               \
+static void __name##_sorted__insert(struct __name##_sorted *sorted,            \
+                                     struct rb_node *sorted_nd)                \
+{                                                                              \
+       struct rb_node **p = &sorted->entries.rb_node, *parent = NULL;          \
+       while (*p != NULL) {                                                    \
+               parent = *p;                                                    \
+               if (__name##_sorted__cmp(sorted_nd, parent))                    \
+                       p = &(*p)->rb_left;                                     \
+               else                                                            \
+                       p = &(*p)->rb_right;                                    \
+       }                                                                       \
+       rb_link_node(sorted_nd, parent, p);                                     \
+       rb_insert_color(sorted_nd, &sorted->entries);                           \
+}                                                                              \
+                                                                               \
+static void __name##_sorted__sort(struct __name##_sorted *sorted,              \
+                                   struct rb_root *entries)                    \
+{                                                                              \
+       struct rb_node *nd;                                                     \
+       unsigned int i = 0;                                                     \
+       for (nd = rb_first(entries); nd; nd = rb_next(nd)) {                    \
+               struct __name##_sorted_entry *snd = &sorted->nd[i++];           \
+               __name##_sorted__init_entry(nd, snd);                           \
+               __name##_sorted__insert(sorted, &snd->rb_node);                 \
+       }                                                                       \
+}                                                                              \
+                                                                               \
+static struct __name##_sorted *__name##_sorted__new(struct rb_root *entries,   \
+                                                   int nr_entries)             \
+{                                                                              \
+       struct __name##_sorted *sorted;                                         \
+       sorted = malloc(sizeof(*sorted) + sizeof(sorted->nd[0]) * nr_entries);  \
+       if (sorted) {                                                           \
+               sorted->entries = RB_ROOT;                                      \
+               __name##_sorted__sort(sorted, entries);                         \
+       }                                                                       \
+       return sorted;                                                          \
+}                                                                              \
+                                                                               \
+static void __name##_sorted__delete(struct __name##_sorted *sorted)            \
+{                                                                              \
+       free(sorted);                                                           \
+}                                                                              \
+                                                                               \
+static void __name##_sorted__init_entry(struct rb_node *nd,                    \
+                                       struct __name##_sorted_entry *entry)
+
+#define DECLARE_RESORT_RB(__name)                                              \
+struct __name##_sorted_entry *__name##_entry;                                  \
+struct __name##_sorted *__name = __name##_sorted__new
+
+#define resort_rb__for_each(__nd, __name)                                      \
+       for (__nd = rb_first(&__name->entries);                                 \
+            __name##_entry = rb_entry(__nd, struct __name##_sorted_entry,      \
+                                      rb_node), __nd;                          \
+            __nd = rb_next(__nd))
+
+#define resort_rb__delete(__name)                                              \
+       __name##_sorted__delete(__name), __name = NULL
+
+/*
+ * Helpers for other classes that contains both an rbtree and the
+ * number of entries in it:
+ */
+
+/* For 'struct intlist' */
+#define DECLARE_RESORT_RB_INTLIST(__name, __ilist)                             \
+       DECLARE_RESORT_RB(__name)(&__ilist->rblist.entries,                     \
+                                 __ilist->rblist.nr_entries)
+
+/* For 'struct machine->threads' */
+#define DECLARE_RESORT_RB_MACHINE_THREADS(__name, __machine)                   \
+       DECLARE_RESORT_RB(__name)(&__machine->threads, __machine->nr_threads)
+
+#endif /* _PERF_RESORT_RB_H_ */