aboutsummaryrefslogtreecommitdiffstats
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.c49
1 files changed, 45 insertions, 4 deletions
diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c
index 706ce1a66169..fd4be94125fb 100644
--- a/tools/perf/util/ordered-events.c
+++ b/tools/perf/util/ordered-events.c
@@ -1,5 +1,6 @@
1#include <linux/list.h> 1#include <linux/list.h>
2#include <linux/compiler.h> 2#include <linux/compiler.h>
3#include <linux/string.h>
3#include "ordered-events.h" 4#include "ordered-events.h"
4#include "evlist.h" 5#include "evlist.h"
5#include "session.h" 6#include "session.h"
@@ -57,11 +58,45 @@ static void queue_event(struct ordered_events *oe, struct ordered_event *new)
57 } 58 }
58} 59}
59 60
61static union perf_event *__dup_event(struct ordered_events *oe,
62 union perf_event *event)
63{
64 union perf_event *new_event = NULL;
65
66 if (oe->cur_alloc_size < oe->max_alloc_size) {
67 new_event = memdup(event, event->header.size);
68 if (new_event)
69 oe->cur_alloc_size += event->header.size;
70 }
71
72 return new_event;
73}
74
75static union perf_event *dup_event(struct ordered_events *oe,
76 union perf_event *event)
77{
78 return oe->copy_on_queue ? __dup_event(oe, event) : event;
79}
80
81static void free_dup_event(struct ordered_events *oe, union perf_event *event)
82{
83 if (oe->copy_on_queue) {
84 oe->cur_alloc_size -= event->header.size;
85 free(event);
86 }
87}
88
60#define MAX_SAMPLE_BUFFER (64 * 1024 / sizeof(struct ordered_event)) 89#define MAX_SAMPLE_BUFFER (64 * 1024 / sizeof(struct ordered_event))
61static struct ordered_event *alloc_event(struct ordered_events *oe) 90static struct ordered_event *alloc_event(struct ordered_events *oe,
91 union perf_event *event)
62{ 92{
63 struct list_head *cache = &oe->cache; 93 struct list_head *cache = &oe->cache;
64 struct ordered_event *new = NULL; 94 struct ordered_event *new = NULL;
95 union perf_event *new_event;
96
97 new_event = dup_event(oe, event);
98 if (!new_event)
99 return NULL;
65 100
66 if (!list_empty(cache)) { 101 if (!list_empty(cache)) {
67 new = list_entry(cache->next, struct ordered_event, list); 102 new = list_entry(cache->next, struct ordered_event, list);
@@ -74,8 +109,10 @@ static struct ordered_event *alloc_event(struct ordered_events *oe)
74 size_t size = MAX_SAMPLE_BUFFER * sizeof(*new); 109 size_t size = MAX_SAMPLE_BUFFER * sizeof(*new);
75 110
76 oe->buffer = malloc(size); 111 oe->buffer = malloc(size);
77 if (!oe->buffer) 112 if (!oe->buffer) {
113 free_dup_event(oe, new_event);
78 return NULL; 114 return NULL;
115 }
79 116
80 pr("alloc size %" PRIu64 "B (+%zu), max %" PRIu64 "B\n", 117 pr("alloc size %" PRIu64 "B (+%zu), max %" PRIu64 "B\n",
81 oe->cur_alloc_size, size, oe->max_alloc_size); 118 oe->cur_alloc_size, size, oe->max_alloc_size);
@@ -90,15 +127,17 @@ static struct ordered_event *alloc_event(struct ordered_events *oe)
90 pr("allocation limit reached %" PRIu64 "B\n", oe->max_alloc_size); 127 pr("allocation limit reached %" PRIu64 "B\n", oe->max_alloc_size);
91 } 128 }
92 129
130 new->event = new_event;
93 return new; 131 return new;
94} 132}
95 133
96struct ordered_event * 134struct ordered_event *
97ordered_events__new(struct ordered_events *oe, u64 timestamp) 135ordered_events__new(struct ordered_events *oe, u64 timestamp,
136 union perf_event *event)
98{ 137{
99 struct ordered_event *new; 138 struct ordered_event *new;
100 139
101 new = alloc_event(oe); 140 new = alloc_event(oe, event);
102 if (new) { 141 if (new) {
103 new->timestamp = timestamp; 142 new->timestamp = timestamp;
104 queue_event(oe, new); 143 queue_event(oe, new);
@@ -111,6 +150,7 @@ void ordered_events__delete(struct ordered_events *oe, struct ordered_event *eve
111{ 150{
112 list_move(&event->list, &oe->cache); 151 list_move(&event->list, &oe->cache);
113 oe->nr_events--; 152 oe->nr_events--;
153 free_dup_event(oe, event->event);
114} 154}
115 155
116static int __ordered_events__flush(struct perf_session *s, 156static int __ordered_events__flush(struct perf_session *s,
@@ -240,6 +280,7 @@ void ordered_events__free(struct ordered_events *oe)
240 280
241 event = list_entry(oe->to_free.next, struct ordered_event, list); 281 event = list_entry(oe->to_free.next, struct ordered_event, list);
242 list_del(&event->list); 282 list_del(&event->list);
283 free_dup_event(oe, event->event);
243 free(event); 284 free(event);
244 } 285 }
245} 286}