On Tue, Jun 20, 2017 at 06:22:56PM +0300, Alexey Budankov wrote:
On 20.06.2017 16:36, Mark Rutland wrote:
On Mon, Jun 19, 2017 at 11:31:59PM +0300, Alexey Budankov wrote:
On 15.06.2017 22:56, Mark Rutland wrote:
On Thu, Jun 15, 2017 at 08:41:42PM +0300, Alexey Budankov wrote:
+static int
+perf_cpu_tree_iterate(struct rb_root *tree,
+ perf_cpu_tree_callback_t callback, void *data)
+{
+ int ret = 0;
+ struct rb_node *node;
+ struct perf_event *event;
+
+ WARN_ON_ONCE(!tree);
+
+ for (node = rb_first(tree); node; node = rb_next(node)) {
+ struct perf_event *node_event = container_of(node,
+ struct perf_event, group_node);
+
+ list_for_each_entry(event, &node_event->group_list,
+ group_list_entry) {
+ ret = callback(event, data);
+ if (ret)
+ return ret;
+ }
+ }
+
+ return 0;
}
If you need to iterate over every event, you can use the list that
threads the whole tree.
Could you please explain more on that?
In Peter's original suggestion, we'd use a threaded tree rather than a
tree of lists.
i.e. you'd have something like:
struct threaded_rb_node {
struct rb_node node;
struct list_head head;
};
Is this for every group leader?
Yes; *every* group leader would be directly in the threaded rb tree.
Which objects does the head keep?
Sorry, I'm not sure how to answer that. Did the above clarify?
If not, could you rephrase the question?
Thanks,
Mark.