@@ -56,11 +56,8 @@ struct handle_list {
struct tracecmd_input *handle;
const char *file;
int cpus;
- int done;
- struct tep_record *record;
struct filter *event_filters;
struct filter *event_filter_out;
- unsigned long long *last_timestamp;
};
static struct list_head handle_list;
@@ -1088,92 +1085,6 @@ test_stacktrace(struct handle_list *handles, struct tep_record *record,
return 0;
}
-static struct tep_record *get_next_record(struct handle_list *handles)
-{
- struct tep_record *record;
- struct tep_handle *pevent;
- int found = 0;
- int cpu;
- int ret;
-
- if (handles->record)
- return handles->record;
-
- if (handles->done)
- return NULL;
-
- pevent = tracecmd_get_tep(handles->handle);
-
- do {
- if (filter_cpus) {
- long long last_stamp = -1;
- struct tep_record *precord;
- int first_record = 1;
- int next_cpu = -1;
- int i;
-
- for (i = 0; (cpu = filter_cpus[i]) >= 0; i++) {
- precord = tracecmd_peek_data(handles->handle, cpu);
- if (precord &&
- (first_record || precord->ts < last_stamp)) {
- next_cpu = cpu;
- last_stamp = precord->ts;
- first_record = 0;
- }
- }
- if (!first_record)
- record = tracecmd_read_data(handles->handle, next_cpu);
- else
- record = NULL;
- } else
- record = tracecmd_read_next_data(handles->handle, &cpu);
-
- if (record) {
- ret = test_filters(pevent, handles->event_filters, record, 0);
- switch (ret) {
- case FILTER_NOEXIST:
- /* Stack traces may still filter this */
- if (stacktrace_id &&
- test_stacktrace(handles, record, 0))
- found = 1;
- else
- tracecmd_free_record(record);
- break;
- case FILTER_NONE:
- case FILTER_MATCH:
- /* Test the negative filters (-v) */
- ret = test_filters(pevent, handles->event_filter_out,
- record, 1);
- if (ret != FILTER_MATCH) {
- found = 1;
- break;
- }
- /* fall through */
- default:
- tracecmd_free_record(record);
- }
- }
- } while (record && !found);
-
- if (record && stacktrace_id)
- test_stacktrace(handles, record, 1);
-
- handles->record = record;
- if (!record)
- handles->done = 1;
-
- return record;
-}
-
-static void free_handle_record(struct handle_list *handles)
-{
- if (!handles->record)
- return;
-
- tracecmd_free_record(handles->record);
- handles->record = NULL;
-}
-
static void print_handle_file(struct handle_list *handles)
{
/* Only print file names if more than one file is read */
@@ -1198,6 +1109,75 @@ static void free_filters(struct filter *event_filter)
}
}
+static bool skip_record(struct handle_list *handles, struct tep_record *record, int cpu)
+{
+ struct tep_handle *tep;
+ bool found = false;
+ int ret;
+
+ tep = tracecmd_get_tep(handles->handle);
+
+ if (filter_cpus) {
+ int i;
+
+ for (i = 0; filter_cpus[i] >= 0; i++) {
+ if (filter_cpus[i] == cpu) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ return true;
+ found = false;
+ }
+
+ ret = test_filters(tep, handles->event_filters, record, 0);
+ switch (ret) {
+ case FILTER_NOEXIST:
+ /* Stack traces may still filter this */
+ if (stacktrace_id &&
+ test_stacktrace(handles, record, 0))
+ found = true;
+ break;
+ case FILTER_NONE:
+ case FILTER_MATCH:
+ /* Test the negative filters (-v) */
+ ret = test_filters(tep, handles->event_filter_out,
+ record, 1);
+ if (ret != FILTER_MATCH) {
+ found = true;
+ break;
+ }
+ }
+
+ if (record && stacktrace_id)
+ test_stacktrace(handles, record, 1);
+
+ return !found;
+}
+
+static int process_record(struct tracecmd_input *handle, struct tep_record *record,
+ int cpu, void *data)
+{
+ struct handle_list *handles = tracecmd_get_private(handle);
+ unsigned long long *last_timestamp = data;
+
+ if (skip_record(handles, record, cpu))
+ return 0;
+
+ if (tscheck && *last_timestamp > record->ts) {
+ errno = 0;
+ warning("WARNING: Record on cpu %d went backwards: %lld to %lld delta: -%lld\n",
+ cpu, *last_timestamp, record->ts, *last_timestamp - record->ts);
+ }
+ *last_timestamp = record->ts;
+
+ print_handle_file(handles);
+ trace_show_data(handle, record);
+ return 0;
+}
+
enum output_type {
OUTPUT_NORMAL,
OUTPUT_STAT_ONLY,
@@ -1210,17 +1190,19 @@ static void read_data_info(struct list_head *handle_list, enum output_type otype
{
unsigned long long ts, first_ts;
struct handle_list *handles;
- struct handle_list *last_handle;
- struct tep_record *record;
- struct tep_record *last_record;
+ struct tracecmd_input **handle_array;
struct tep_handle *pevent;
struct tep_event *event;
+ unsigned long long last_timestamp = 0;
+ int nr_handles = 0;
int first = 1;
int ret;
list_for_each_entry(handles, handle_list, list) {
int cpus;
+ nr_handles++;
+
if (!tracecmd_is_buffer_instance(handles->handle)) {
ret = tracecmd_init_data(handles->handle);
if (ret < 0)
@@ -1228,9 +1210,6 @@ static void read_data_info(struct list_head *handle_list, enum output_type otype
}
cpus = tracecmd_cpus(handles->handle);
handles->cpus = cpus;
- handles->last_timestamp = calloc(cpus, sizeof(*handles->last_timestamp));
- if (!handles->last_timestamp)
- die("allocating timestamps");
/* Don't process instances that we added here */
if (tracecmd_is_buffer_instance(handles->handle))
@@ -1315,38 +1294,20 @@ static void read_data_info(struct list_head *handle_list, enum output_type otype
}
}
- do {
- last_handle = NULL;
- last_record = NULL;
+ handle_array = calloc(nr_handles, sizeof(*handle_array));
+ if (!handle_array)
+ die("Could not allocate memory for handle list");
- list_for_each_entry(handles, handle_list, list) {
- record = get_next_record(handles);
- if (!record)
- continue;
- if (!last_record ||
- (record && record->ts < last_record->ts)) {
- last_record = record;
- last_handle = handles;
- }
- }
- if (last_record) {
- int cpu = last_record->cpu;
- if (cpu >= last_handle->cpus)
- die("cpu %d greater than %d\n", cpu, last_handle->cpus);
- if (tscheck &&
- last_handle->last_timestamp[cpu] > last_record->ts) {
- errno = 0;
- warning("WARNING: Record on cpu %d went backwards: %lld to %lld delta: -%lld\n",
- cpu, last_handle->last_timestamp[cpu],
- last_record->ts,
- last_handle->last_timestamp[cpu] - last_record->ts);
- }
- last_handle->last_timestamp[cpu] = last_record->ts;
- print_handle_file(last_handle);
- trace_show_data(last_handle->handle, last_record);
- free_handle_record(last_handle);
- }
- } while (last_record);
+ nr_handles = 0;
+ list_for_each_entry(handles, handle_list, list) {
+ tracecmd_set_private(handles->handle, handles);
+ handle_array[nr_handles++] = handles->handle;
+ }
+
+ tracecmd_iterate_events_multi(handle_array, nr_handles,
+ process_record, &last_timestamp);
+
+ free(handle_array);
if (profile)
do_trace_profile();
@@ -1354,7 +1315,6 @@ static void read_data_info(struct list_head *handle_list, enum output_type otype
list_for_each_entry(handles, handle_list, list) {
free_filters(handles->event_filters);
free_filters(handles->event_filter_out);
- free(handles->last_timestamp);
show_test(handles->handle);
}