From: "Steven Rostedt (Google)" <rostedt@xxxxxxxxxxx> Add a helper function that will iterate over a list of events for a given handle. Requires the handle to be opened and ready for reading. Signed-off-by: Steven Rostedt (Google) <rostedt@xxxxxxxxxxx> --- include/trace-cmd/trace-cmd.h | 7 ++++ lib/trace-cmd/trace-input.c | 70 +++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/include/trace-cmd/trace-cmd.h b/include/trace-cmd/trace-cmd.h index 5d71e8bab186..b91235751d64 100644 --- a/include/trace-cmd/trace-cmd.h +++ b/include/trace-cmd/trace-cmd.h @@ -48,6 +48,13 @@ int tracecmd_buffer_instances(struct tracecmd_input *handle); const char *tracecmd_buffer_instance_name(struct tracecmd_input *handle, int indx); struct tracecmd_input *tracecmd_buffer_instance_handle(struct tracecmd_input *handle, int indx); +int tracecmd_iterate_events(struct tracecmd_input *handle, + cpu_set_t *cpus, int cpu_size, + int (*callback)(struct tracecmd_input *handle, + struct tep_record *, + int, void *), + void *callback_data); + void tracecmd_set_loglevel(enum tep_loglevel level); #endif /* _TRACE_CMD_H */ diff --git a/lib/trace-cmd/trace-input.c b/lib/trace-cmd/trace-input.c index 0fef2ca7bb70..e990600ad6b1 100644 --- a/lib/trace-cmd/trace-input.c +++ b/lib/trace-cmd/trace-input.c @@ -2511,6 +2511,76 @@ tracecmd_read_next_data(struct tracecmd_input *handle, int *rec_cpu) return tracecmd_read_data(handle, next_cpu); } +/** + * tracecmd_iterate_events - iterate events over a given handle + * @handle: The handle to iterate over + * @cpus: The CPU set to filter on (NULL for all CPUs) + * @cpu_size: The size of @cpus (ignored if @cpus is NULL) + * @callback: The callback function for each event + * @callback_data: The data to pass to the @callback. + * + * Will loop over all events in @handle (filtered by the given @cpus), + * and will call @callback for each event in order of the event's records + * timestamp. + * + * Returns the -1 on error, or the value of the callbacks. + */ +int tracecmd_iterate_events(struct tracecmd_input *handle, + cpu_set_t *cpus, int cpu_size, + int (*callback)(struct tracecmd_input *handle, + struct tep_record *, + int, void *), + void *callback_data) +{ + struct tep_record **records; + struct tep_record *record; + unsigned long long last_timestamp = 0; + int next_cpu; + int cpu; + int ret = 0; + + records = calloc(handle->max_cpu, sizeof(*records)); + if (!records) + return -1; + + for (cpu = 0; cpu < handle->max_cpu; cpu++) { + if (cpus && !CPU_ISSET_S(cpu, cpu_size, cpus)) + continue; + + records[cpu] = tracecmd_peek_data(handle, cpu); + } + + do { + next_cpu = -1; + for (cpu = 0; cpu < handle->max_cpu; cpu++) { + record = records[cpu]; + if (!record) + continue; + + if (next_cpu < 0 || record->ts < last_timestamp) { + next_cpu = cpu; + last_timestamp = record->ts; + } + } + if (next_cpu >= 0) { + /* Need to call read_data to increment to the next record */ + record = tracecmd_read_data(handle, next_cpu); + records[next_cpu] = tracecmd_peek_data(handle, next_cpu); + + ret = callback(handle, record, next_cpu, callback_data); + tracecmd_free_record(record); + } + + } while (next_cpu >= 0 && ret >= 0); + + for (cpu = 0; cpu < handle->max_cpu; cpu++) + tracecmd_free_record(records[cpu]); + + free(records); + + return ret; +} + /** * tracecmd_peek_next_data - return the next record * @handle: input handle to the trace.dat file -- 2.35.1