From 5f86b80b85f0dcd05fd1471eac6984181a707c4f Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 1 Aug 2014 13:02:58 -0300 Subject: perf tools: Create ordered-events object Move ordered events code into separated object ordered-events.[ch]. No functional change was intended. Signed-off-by: Jiri Olsa Acked-by: David Ahern Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-1ge3rilgudszbl87cejm1tfg@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/session.c | 206 ---------------------------------------------- 1 file changed, 206 deletions(-) (limited to 'tools/perf/util/session.c') diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index ed6b7f1..0ccf051 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -14,7 +14,6 @@ #include "util.h" #include "cpumap.h" #include "perf_regs.h" -#include "asm/bug.h" static int perf_session__open(struct perf_session *session) { @@ -447,19 +446,6 @@ static perf_event__swap_op perf_event__swap_ops[] = { [PERF_RECORD_HEADER_MAX] = NULL, }; -struct ordered_event { - u64 timestamp; - u64 file_offset; - union perf_event *event; - struct list_head list; -}; - -enum oe_flush { - OE_FLUSH__FINAL, - OE_FLUSH__ROUND, - OE_FLUSH__HALF, -}; - static void perf_session_free_sample_buffers(struct perf_session *session) { struct ordered_events *oe = &session->ordered_events; @@ -473,198 +459,6 @@ static void perf_session_free_sample_buffers(struct perf_session *session) } } -/* The queue is ordered by time */ -static void queue_event(struct ordered_events *oe, struct ordered_event *new) -{ - struct ordered_event *last = oe->last; - u64 timestamp = new->timestamp; - struct list_head *p; - - ++oe->nr_events; - oe->last = new; - - if (!last) { - list_add(&new->list, &oe->events); - oe->max_timestamp = timestamp; - return; - } - - /* - * last event might point to some random place in the list as it's - * the last queued event. We expect that the new event is close to - * this. - */ - if (last->timestamp <= timestamp) { - while (last->timestamp <= timestamp) { - p = last->list.next; - if (p == &oe->events) { - list_add_tail(&new->list, &oe->events); - oe->max_timestamp = timestamp; - return; - } - last = list_entry(p, struct ordered_event, list); - } - list_add_tail(&new->list, &last->list); - } else { - while (last->timestamp > timestamp) { - p = last->list.prev; - if (p == &oe->events) { - list_add(&new->list, &oe->events); - return; - } - last = list_entry(p, struct ordered_event, list); - } - list_add(&new->list, &last->list); - } -} - -#define MAX_SAMPLE_BUFFER (64 * 1024 / sizeof(struct ordered_event)) -static struct ordered_event *alloc_event(struct ordered_events *oe) -{ - struct list_head *cache = &oe->cache; - struct ordered_event *new = NULL; - - if (!list_empty(cache)) { - new = list_entry(cache->next, struct ordered_event, list); - list_del(&new->list); - } else if (oe->buffer) { - new = oe->buffer + oe->buffer_idx; - if (++oe->buffer_idx == MAX_SAMPLE_BUFFER) - oe->buffer = NULL; - } else if (oe->cur_alloc_size < oe->max_alloc_size) { - size_t size = MAX_SAMPLE_BUFFER * sizeof(*new); - - oe->buffer = malloc(size); - if (!oe->buffer) - return NULL; - - oe->cur_alloc_size += size; - list_add(&oe->buffer->list, &oe->to_free); - - /* First entry is abused to maintain the to_free list. */ - oe->buffer_idx = 2; - new = oe->buffer + 1; - } - - return new; -} - -static struct ordered_event * -ordered_events__new(struct ordered_events *oe, u64 timestamp) -{ - struct ordered_event *new; - - new = alloc_event(oe); - if (new) { - new->timestamp = timestamp; - queue_event(oe, new); - } - - return new; -} - -static void -ordered_events__delete(struct ordered_events *oe, struct ordered_event *event) -{ - list_del(&event->list); - list_add(&event->list, &oe->cache); - oe->nr_events--; -} - -static int __ordered_events__flush(struct perf_session *s, - struct perf_tool *tool) -{ - struct ordered_events *oe = &s->ordered_events; - struct list_head *head = &oe->events; - struct ordered_event *tmp, *iter; - struct perf_sample sample; - u64 limit = oe->next_flush; - u64 last_ts = oe->last ? oe->last->timestamp : 0ULL; - bool show_progress = limit == ULLONG_MAX; - struct ui_progress prog; - int ret; - - if (!tool->ordered_events || !limit) - return 0; - - if (show_progress) - ui_progress__init(&prog, oe->nr_events, "Processing time ordered events..."); - - list_for_each_entry_safe(iter, tmp, head, list) { - if (session_done()) - return 0; - - if (iter->timestamp > limit) - break; - - ret = perf_evlist__parse_sample(s->evlist, iter->event, &sample); - if (ret) - pr_err("Can't parse sample, err = %d\n", ret); - else { - ret = perf_session__deliver_event(s, iter->event, &sample, tool, - iter->file_offset); - if (ret) - return ret; - } - - ordered_events__delete(oe, iter); - oe->last_flush = iter->timestamp; - - if (show_progress) - ui_progress__update(&prog, 1); - } - - if (list_empty(head)) - oe->last = NULL; - else if (last_ts <= limit) - oe->last = list_entry(head->prev, struct ordered_event, list); - - return 0; -} - -static int ordered_events__flush(struct perf_session *s, struct perf_tool *tool, - enum oe_flush how) -{ - struct ordered_events *oe = &s->ordered_events; - int err; - - switch (how) { - case OE_FLUSH__FINAL: - oe->next_flush = ULLONG_MAX; - break; - - case OE_FLUSH__HALF: - { - struct ordered_event *first, *last; - struct list_head *head = &oe->events; - - first = list_entry(head->next, struct ordered_event, list); - last = oe->last; - - /* Warn if we are called before any event got allocated. */ - if (WARN_ONCE(!last || list_empty(head), "empty queue")) - return 0; - - oe->next_flush = first->timestamp; - oe->next_flush += (last->timestamp - first->timestamp) / 2; - break; - } - - case OE_FLUSH__ROUND: - default: - break; - }; - - err = __ordered_events__flush(s, tool); - - if (!err) { - if (how == OE_FLUSH__ROUND) - oe->next_flush = oe->max_timestamp; - } - - return err; -} - /* * When perf record finishes a pass on every buffers, it records this pseudo * event. -- cgit v1.1