[PATCH 10/18] perf tools: Create ordered-events object
Move ordered events code into separated object ordered-events.[ch]. Cc: Arnaldo Carvalho de Melo Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Signed-off-by: Jiri Olsa --- tools/perf/Makefile.perf | 2 + tools/perf/util/ordered-events.c | 195 + tools/perf/util/ordered-events.h | 43 tools/perf/util/session.c| 205 --- tools/perf/util/session.h| 17 +--- 5 files changed, 241 insertions(+), 221 deletions(-) create mode 100644 tools/perf/util/ordered-events.c create mode 100644 tools/perf/util/ordered-events.h diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 9670a16..1351cfe 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -263,6 +263,7 @@ LIB_H += util/xyarray.h LIB_H += util/header.h LIB_H += util/help.h LIB_H += util/session.h +LIB_H += util/ordered-events.h LIB_H += util/strbuf.h LIB_H += util/strlist.h LIB_H += util/strfilter.h @@ -345,6 +346,7 @@ LIB_OBJS += $(OUTPUT)util/machine.o LIB_OBJS += $(OUTPUT)util/map.o LIB_OBJS += $(OUTPUT)util/pstack.o LIB_OBJS += $(OUTPUT)util/session.o +LIB_OBJS += $(OUTPUT)util/ordered-events.o LIB_OBJS += $(OUTPUT)util/comm.o LIB_OBJS += $(OUTPUT)util/thread.o LIB_OBJS += $(OUTPUT)util/thread_map.o diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c new file mode 100644 index 000..2e89bea --- /dev/null +++ b/tools/perf/util/ordered-events.c @@ -0,0 +1,195 @@ +#include +#include "ordered-events.h" +#include "evlist.h" +#include "session.h" +#include "asm/bug.h" + +static void queue_event(struct ordered_events_queue *q, struct ordered_event *new) +{ + struct ordered_event *last = q->last; + u64 timestamp = new->timestamp; + struct list_head *p; + + ++q->nr_events; + q->last = new; + + if (!last) { + list_add(>list, >events); + q->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 clqe to +* this. +*/ + if (last->timestamp <= timestamp) { + while (last->timestamp <= timestamp) { + p = last->list.next; + if (p == >events) { + list_add_tail(>list, >events); + q->max_timestamp = timestamp; + return; + } + last = list_entry(p, struct ordered_event, list); + } + list_add_tail(>list, >list); + } else { + while (last->timestamp > timestamp) { + p = last->list.prev; + if (p == >events) { + list_add(>list, >events); + return; + } + last = list_entry(p, struct ordered_event, list); + } + list_add(>list, >list); + } +} + +#define MAX_SAMPLE_BUFFER (64 * 1024 / sizeof(struct ordered_event)) +static struct ordered_event *alloc_event(struct ordered_events_queue *q) +{ + struct list_head *cache = >cache; + struct ordered_event *new = NULL; + + if (!list_empty(cache)) { + new = list_entry(cache->next, struct ordered_event, list); + list_del(>list); + } else if (q->buffer) { + new = q->buffer + q->buffer_idx; + if (++q->buffer_idx == MAX_SAMPLE_BUFFER) + q->buffer = NULL; + } else if (q->cur_alloc_size < q->max_alloc_size) { + size_t size = MAX_SAMPLE_BUFFER * sizeof(*new); + + q->buffer = malloc(size); + if (!q->buffer) + return NULL; + + q->cur_alloc_size += size; + list_add(>buffer->list, >to_free); + + /* First entry is abused to maintain the to_free list. */ + q->buffer_idx = 2; + new = q->buffer + 1; + } + + return new; +} + +struct ordered_event* +ordered_events_get(struct ordered_events_queue *q, u64 timestamp) +{ + struct ordered_event *new; + + new = alloc_event(q); + if (new) { + new->timestamp = timestamp; + queue_event(q, new); + } + + return new; +} + +void +ordered_event_put(struct ordered_events_queue *q, struct ordered_event *iter) +{ + list_del(>list); + list_add(>list, >cache); + q->nr_events--; +} + +static int __ordered_events_flush(struct perf_session *s, + struct perf_tool *tool) +{ + struct ordered_events_queue *q = >ordered_events;
[PATCH 10/18] perf tools: Create ordered-events object
Move ordered events code into separated object ordered-events.[ch]. Cc: Arnaldo Carvalho de Melo a...@kernel.org Cc: Corey Ashford cjash...@linux.vnet.ibm.com Cc: David Ahern dsah...@gmail.com Cc: Frederic Weisbecker fweis...@gmail.com Cc: Ingo Molnar mi...@kernel.org Cc: Jean Pihet jean.pi...@linaro.org Cc: Namhyung Kim namhy...@kernel.org Cc: Paul Mackerras pau...@samba.org Cc: Peter Zijlstra a.p.zijls...@chello.nl Signed-off-by: Jiri Olsa jo...@kernel.org --- tools/perf/Makefile.perf | 2 + tools/perf/util/ordered-events.c | 195 + tools/perf/util/ordered-events.h | 43 tools/perf/util/session.c| 205 --- tools/perf/util/session.h| 17 +--- 5 files changed, 241 insertions(+), 221 deletions(-) create mode 100644 tools/perf/util/ordered-events.c create mode 100644 tools/perf/util/ordered-events.h diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 9670a16..1351cfe 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -263,6 +263,7 @@ LIB_H += util/xyarray.h LIB_H += util/header.h LIB_H += util/help.h LIB_H += util/session.h +LIB_H += util/ordered-events.h LIB_H += util/strbuf.h LIB_H += util/strlist.h LIB_H += util/strfilter.h @@ -345,6 +346,7 @@ LIB_OBJS += $(OUTPUT)util/machine.o LIB_OBJS += $(OUTPUT)util/map.o LIB_OBJS += $(OUTPUT)util/pstack.o LIB_OBJS += $(OUTPUT)util/session.o +LIB_OBJS += $(OUTPUT)util/ordered-events.o LIB_OBJS += $(OUTPUT)util/comm.o LIB_OBJS += $(OUTPUT)util/thread.o LIB_OBJS += $(OUTPUT)util/thread_map.o diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c new file mode 100644 index 000..2e89bea --- /dev/null +++ b/tools/perf/util/ordered-events.c @@ -0,0 +1,195 @@ +#include linux/list.h +#include ordered-events.h +#include evlist.h +#include session.h +#include asm/bug.h + +static void queue_event(struct ordered_events_queue *q, struct ordered_event *new) +{ + struct ordered_event *last = q-last; + u64 timestamp = new-timestamp; + struct list_head *p; + + ++q-nr_events; + q-last = new; + + if (!last) { + list_add(new-list, q-events); + q-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 clqe to +* this. +*/ + if (last-timestamp = timestamp) { + while (last-timestamp = timestamp) { + p = last-list.next; + if (p == q-events) { + list_add_tail(new-list, q-events); + q-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 == q-events) { + list_add(new-list, q-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_queue *q) +{ + struct list_head *cache = q-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 (q-buffer) { + new = q-buffer + q-buffer_idx; + if (++q-buffer_idx == MAX_SAMPLE_BUFFER) + q-buffer = NULL; + } else if (q-cur_alloc_size q-max_alloc_size) { + size_t size = MAX_SAMPLE_BUFFER * sizeof(*new); + + q-buffer = malloc(size); + if (!q-buffer) + return NULL; + + q-cur_alloc_size += size; + list_add(q-buffer-list, q-to_free); + + /* First entry is abused to maintain the to_free list. */ + q-buffer_idx = 2; + new = q-buffer + 1; + } + + return new; +} + +struct ordered_event* +ordered_events_get(struct ordered_events_queue *q, u64 timestamp) +{ + struct ordered_event *new; + + new = alloc_event(q); + if (new) { + new-timestamp = timestamp; + queue_event(q, new); + } + + return new; +} + +void +ordered_event_put(struct ordered_events_queue *q, struct ordered_event *iter) +{ + list_del(iter-list); + list_add(iter-list, q-cache); +