summaryrefslogtreecommitdiff
path: root/tools/perf/util/ordered-events.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/ordered-events.c')
-rw-r--r--tools/perf/util/ordered-events.c62
1 files changed, 48 insertions, 14 deletions
diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c
index fd4be94125fb..6002fa3fcf77 100644
--- a/tools/perf/util/ordered-events.c
+++ b/tools/perf/util/ordered-events.c
@@ -131,8 +131,8 @@ static struct ordered_event *alloc_event(struct ordered_events *oe,
return new;
}
-struct ordered_event *
-ordered_events__new(struct ordered_events *oe, u64 timestamp,
+static struct ordered_event *
+ordered_events__new_event(struct ordered_events *oe, u64 timestamp,
union perf_event *event)
{
struct ordered_event *new;
@@ -153,10 +153,38 @@ void ordered_events__delete(struct ordered_events *oe, struct ordered_event *eve
free_dup_event(oe, event->event);
}
-static int __ordered_events__flush(struct perf_session *s,
- struct perf_tool *tool)
+int ordered_events__queue(struct ordered_events *oe, union perf_event *event,
+ struct perf_sample *sample, u64 file_offset)
+{
+ u64 timestamp = sample->time;
+ struct ordered_event *oevent;
+
+ if (!timestamp || timestamp == ~0ULL)
+ return -ETIME;
+
+ if (timestamp < oe->last_flush) {
+ pr_oe_time(timestamp, "out of order event\n");
+ pr_oe_time(oe->last_flush, "last flush, last_flush_type %d\n",
+ oe->last_flush_type);
+
+ oe->evlist->stats.nr_unordered_events++;
+ }
+
+ oevent = ordered_events__new_event(oe, timestamp, event);
+ if (!oevent) {
+ ordered_events__flush(oe, OE_FLUSH__HALF);
+ oevent = ordered_events__new_event(oe, timestamp, event);
+ }
+
+ if (!oevent)
+ return -ENOMEM;
+
+ oevent->file_offset = file_offset;
+ return 0;
+}
+
+static int __ordered_events__flush(struct ordered_events *oe)
{
- struct ordered_events *oe = &s->ordered_events;
struct list_head *head = &oe->events;
struct ordered_event *tmp, *iter;
struct perf_sample sample;
@@ -166,7 +194,7 @@ static int __ordered_events__flush(struct perf_session *s,
struct ui_progress prog;
int ret;
- if (!tool->ordered_events || !limit)
+ if (!limit)
return 0;
if (show_progress)
@@ -179,12 +207,11 @@ static int __ordered_events__flush(struct perf_session *s,
if (iter->timestamp > limit)
break;
- ret = perf_evlist__parse_sample(s->evlist, iter->event, &sample);
+ ret = perf_evlist__parse_sample(oe->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);
+ ret = oe->deliver(oe, iter, &sample);
if (ret)
return ret;
}
@@ -204,10 +231,8 @@ static int __ordered_events__flush(struct perf_session *s,
return 0;
}
-int ordered_events__flush(struct perf_session *s, struct perf_tool *tool,
- enum oe_flush how)
+int ordered_events__flush(struct ordered_events *oe, enum oe_flush how)
{
- struct ordered_events *oe = &s->ordered_events;
static const char * const str[] = {
"NONE",
"FINAL",
@@ -216,6 +241,9 @@ int ordered_events__flush(struct perf_session *s, struct perf_tool *tool,
};
int err;
+ if (oe->nr_events == 0)
+ return 0;
+
switch (how) {
case OE_FLUSH__FINAL:
oe->next_flush = ULLONG_MAX;
@@ -248,7 +276,7 @@ int ordered_events__flush(struct perf_session *s, struct perf_tool *tool,
str[how], oe->nr_events);
pr_oe_time(oe->max_timestamp, "max_timestamp\n");
- err = __ordered_events__flush(s, tool);
+ err = __ordered_events__flush(oe);
if (!err) {
if (how == OE_FLUSH__ROUND)
@@ -264,13 +292,19 @@ int ordered_events__flush(struct perf_session *s, struct perf_tool *tool,
return err;
}
-void ordered_events__init(struct ordered_events *oe)
+void ordered_events__init(struct ordered_events *oe, struct machines *machines,
+ struct perf_evlist *evlist, struct perf_tool *tool,
+ ordered_events__deliver_t deliver)
{
INIT_LIST_HEAD(&oe->events);
INIT_LIST_HEAD(&oe->cache);
INIT_LIST_HEAD(&oe->to_free);
oe->max_alloc_size = (u64) -1;
oe->cur_alloc_size = 0;
+ oe->evlist = evlist;
+ oe->machines = machines;
+ oe->tool = tool;
+ oe->deliver = deliver;
}
void ordered_events__free(struct ordered_events *oe)