aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2010-02-08 11:43:59 -0500
committerSteven Rostedt <rostedt@goodmis.org>2010-02-08 14:49:51 -0500
commit0147df4b777ade75785c4667ef4b6e5642ca6590 (patch)
treeffcde3cb5e75231c2e01d1a2e07206f4b1065885
parent38e4c3fb1424da4b4a6eebe808108907fc31a43b (diff)
trace-cmd: Add new tracecmd_set_cursor() function
The tracecmd_set_cursor() takes an offset that will cause the next tracecmd_peek_data() or tracecmd_read_data() to return a record at that offset (given that the CPU matches). This is useful when iterating with tracecmd_read_data() and then needing to read a record out of sequence. One can do: while ((record = tracecmd_read_data(h, cpu))) { /* ... */ free_record(record); record = tracecmd_peek_data(h, cpu); save_offset = record->offset; free_record(record); record = tracecmd_read_at(h, o, NULL); /* ... */ tracecmd_set_cursor(h, cpu, save_offset); } Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--trace-cmd.h3
-rw-r--r--trace-input.c94
2 files changed, 85 insertions, 12 deletions
diff --git a/trace-cmd.h b/trace-cmd.h
index eda7181..b7cd5cc 100644
--- a/trace-cmd.h
+++ b/trace-cmd.h
@@ -82,6 +82,9 @@ int tracecmd_refresh_record(struct tracecmd_input *handle,
82int tracecmd_set_cpu_to_timestamp(struct tracecmd_input *handle, 82int tracecmd_set_cpu_to_timestamp(struct tracecmd_input *handle,
83 int cpu, unsigned long long ts); 83 int cpu, unsigned long long ts);
84 84
85int tracecmd_set_cursor(struct tracecmd_input *handle,
86 int cpu, unsigned long long offset);
87
85int tracecmd_ftrace_overrides(struct tracecmd_input *handle); 88int tracecmd_ftrace_overrides(struct tracecmd_input *handle);
86struct pevent *tracecmd_get_pevent(struct tracecmd_input *handle); 89struct pevent *tracecmd_get_pevent(struct tracecmd_input *handle);
87 90
diff --git a/trace-input.c b/trace-input.c
index 884dd2f..3191510 100644
--- a/trace-input.c
+++ b/trace-input.c
@@ -816,13 +816,13 @@ read_old_format(struct tracecmd_input *handle, void **ptr, int cpu)
816} 816}
817 817
818static struct record * 818static struct record *
819read_event(struct tracecmd_input *handle, unsigned long long offset, 819peek_event(struct tracecmd_input *handle, unsigned long long offset,
820 int cpu) 820 int cpu)
821{ 821{
822 struct record *record = NULL; 822 struct record *record = NULL;
823 823
824 /* 824 /*
825 * Since the timestamp is calculated from the beginnnig 825 * Since the timestamp is calculated from the beginning
826 * of the page and through each event, we reset the 826 * of the page and through each event, we reset the
827 * page to the beginning. This is just used by 827 * page to the beginning. This is just used by
828 * tracecmd_read_at. 828 * tracecmd_read_at.
@@ -834,21 +834,30 @@ read_event(struct tracecmd_input *handle, unsigned long long offset,
834 } 834 }
835 835
836 do { 836 do {
837 if (record) 837 free_record(record);
838 free_record(record); 838 record = tracecmd_peek_data(handle, cpu);
839 /* Make sure peek returns new data */ 839 if (record && (record->offset + record->record_size) > offset)
840 if (handle->cpu_data[cpu].next) { 840 break;
841 free_record(handle->cpu_data[cpu].next);
842 handle->cpu_data[cpu].next = NULL;
843 }
844 record = tracecmd_read_data(handle, cpu); 841 record = tracecmd_read_data(handle, cpu);
845 } while (record && (record->offset + record->record_size) <= offset); 842 } while (record);
846 843
847 return record; 844 return record;
848} 845}
849 846
850static struct record * 847static struct record *
851find_and_read_event(struct tracecmd_input *handle, unsigned long long offset, 848read_event(struct tracecmd_input *handle, unsigned long long offset,
849 int cpu)
850{
851 struct record *record;
852
853 record = peek_event(handle, offset, cpu);
854 if (record)
855 record = tracecmd_read_data(handle, cpu);
856 return record;
857}
858
859static struct record *
860find_and_peek_event(struct tracecmd_input *handle, unsigned long long offset,
852 int *pcpu) 861 int *pcpu)
853{ 862{
854 unsigned long long page_offset; 863 unsigned long long page_offset;
@@ -875,7 +884,24 @@ find_and_read_event(struct tracecmd_input *handle, unsigned long long offset,
875 if (pcpu) 884 if (pcpu)
876 *pcpu = cpu; 885 *pcpu = cpu;
877 886
878 return read_event(handle, offset, cpu); 887 return peek_event(handle, offset, cpu);
888}
889
890
891static struct record *
892find_and_read_event(struct tracecmd_input *handle, unsigned long long offset,
893 int *pcpu)
894{
895 struct record *record;
896 int cpu;
897
898 record = find_and_peek_event(handle, offset, &cpu);
899 if (record) {
900 record = tracecmd_read_data(handle, cpu);
901 if (pcpu)
902 *pcpu = cpu;
903 }
904 return record;
879} 905}
880 906
881/** 907/**
@@ -1147,6 +1173,50 @@ tracecmd_set_cpu_to_timestamp(struct tracecmd_input *handle, int cpu,
1147 return 0; 1173 return 0;
1148} 1174}
1149 1175
1176/**
1177 * tracecmd_set_cursor - set the offset for the next tracecmd_read_data
1178 * @handle: input handle for the trace.dat file
1179 * @cpu: the CPU pointer to set
1180 * @offset: the offset to place the cursor
1181 *
1182 * Set the pointer to the next read or peek. This is useful when
1183 * needing to read sequentially and then look at another record
1184 * out of sequence without breaking the iteration. This is done with:
1185 *
1186 * record = tracecmd_peek_data()
1187 * offset = record->offset;
1188 * record = tracecmd_read_at();
1189 * - do what ever with record -
1190 * tracecmd_set_cursor(handle, cpu, offset);
1191 *
1192 * Now the next tracecmd_peek_data or tracecmd_read_data will return
1193 * the original record.
1194 */
1195int tracecmd_set_cursor(struct tracecmd_input *handle,
1196 int cpu, unsigned long long offset)
1197{
1198 struct cpu_data *cpu_data = &handle->cpu_data[cpu];
1199 unsigned long long page_offset;
1200
1201 if (cpu < 0 || cpu >= handle->cpus)
1202 return -1;
1203
1204 if (offset < cpu_data->file_offset ||
1205 offset > cpu_data->file_offset + cpu_data->file_size)
1206 return -1; /* cpu does not have this offset. */
1207
1208 /* Move this cpu index to point to this offest */
1209 page_offset = offset & ~(handle->page_size - 1);
1210
1211 if (get_page(handle, cpu, page_offset) < 0)
1212 return -1;
1213
1214 peek_event(handle, offset, cpu);
1215
1216 return 0;
1217}
1218
1219
1150static unsigned int 1220static unsigned int
1151translate_data(struct tracecmd_input *handle, 1221translate_data(struct tracecmd_input *handle,
1152 void **ptr, unsigned long long *delta, int *length) 1222 void **ptr, unsigned long long *delta, int *length)