diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2012-01-30 17:40:44 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2012-01-30 17:40:44 -0500 |
commit | 10dd550fb2a71eddd0a2251664d3320a3d09e600 (patch) | |
tree | cbd2b1c1950e386f5647e4ea038e31f97cf41039 /src/ft2csv.c | |
parent | 2089e7a47d1e081cfd2b444e9ffb512732e6d082 (diff) | |
parent | 57069d06ed3b5086bf5ebd87998ae8afedbac7cc (diff) |
Merge branch 'mpi-staging' into mpi-master
Diffstat (limited to 'src/ft2csv.c')
-rw-r--r-- | src/ft2csv.c | 146 |
1 files changed, 105 insertions, 41 deletions
diff --git a/src/ft2csv.c b/src/ft2csv.c index cc6636f..aceeb25 100644 --- a/src/ft2csv.c +++ b/src/ft2csv.c | |||
@@ -30,23 +30,41 @@ | |||
30 | static int want_interleaved = 1; | 30 | static int want_interleaved = 1; |
31 | static int want_best_effort = 0; | 31 | static int want_best_effort = 0; |
32 | 32 | ||
33 | /* discard samples from a specific CPU */ | ||
34 | static int avoid_cpu = -1; | ||
35 | /* only use samples from a specific CPU */ | ||
36 | static int only_cpu = -1; | ||
37 | |||
33 | static unsigned int complete = 0; | 38 | static unsigned int complete = 0; |
34 | static unsigned int incomplete = 0; | 39 | static unsigned int incomplete = 0; |
35 | static unsigned int filtered = 0; | 40 | static unsigned int filtered = 0; |
36 | static unsigned int skipped = 0; | 41 | static unsigned int skipped = 0; |
37 | static unsigned int non_rt = 0; | 42 | static unsigned int non_rt = 0; |
38 | static unsigned int interleaved = 0; | 43 | static unsigned int interleaved = 0; |
44 | static unsigned int avoided = 0; | ||
39 | 45 | ||
40 | #define CYCLES_PER_US 2128 | 46 | #define CYCLES_PER_US 2128 |
41 | 47 | ||
42 | static unsigned long long threshold = CYCLES_PER_US * 1000; /* 1 ms == 1 full tick */ | 48 | static unsigned long long threshold = CYCLES_PER_US * 10000; /* 10 ms == 10 full ticks */ |
43 | 49 | ||
44 | static struct timestamp* next(struct timestamp* start, struct timestamp* end, | 50 | static struct timestamp* next(struct timestamp* start, struct timestamp* end, |
45 | int cpu) | 51 | int cpu) |
46 | { | 52 | { |
47 | struct timestamp* pos; | 53 | struct timestamp* pos; |
48 | for (pos = start; pos != end && pos->cpu != cpu; pos++); | 54 | unsigned int last_seqno = 0; |
49 | return pos != end ? pos : NULL; | 55 | |
56 | for (pos = start; pos != end; pos++) { | ||
57 | /* check for for holes in the sequence number */ | ||
58 | if (last_seqno && last_seqno + 1 != pos->seq_no) { | ||
59 | /* stumbled across a hole */ | ||
60 | return NULL; | ||
61 | } | ||
62 | last_seqno = pos->seq_no; | ||
63 | |||
64 | if (pos->cpu == cpu) | ||
65 | return pos; | ||
66 | } | ||
67 | return NULL; | ||
50 | } | 68 | } |
51 | 69 | ||
52 | static struct timestamp* next_id(struct timestamp* start, struct timestamp* end, | 70 | static struct timestamp* next_id(struct timestamp* start, struct timestamp* end, |
@@ -79,10 +97,35 @@ static struct timestamp* find_second_ts(struct timestamp* start, | |||
79 | start->event); | 97 | start->event); |
80 | } | 98 | } |
81 | 99 | ||
100 | typedef void (*pair_fmt_t)(struct timestamp* first, struct timestamp* second); | ||
101 | |||
102 | static void print_pair_csv(struct timestamp* first, struct timestamp* second) | ||
103 | { | ||
104 | printf("%llu, %llu, %llu\n", | ||
105 | (unsigned long long) first->timestamp, | ||
106 | (unsigned long long) second->timestamp, | ||
107 | (unsigned long long) | ||
108 | (second->timestamp - first->timestamp)); | ||
109 | } | ||
110 | |||
111 | static void print_pair_bin(struct timestamp* first, struct timestamp* second) | ||
112 | { | ||
113 | float delta = second->timestamp - first->timestamp; | ||
114 | fwrite(&delta, sizeof(delta), 1, stdout); | ||
115 | } | ||
116 | |||
117 | pair_fmt_t format_pair = print_pair_csv; | ||
118 | |||
82 | static void show_csv(struct timestamp* first, struct timestamp *end) | 119 | static void show_csv(struct timestamp* first, struct timestamp *end) |
83 | { | 120 | { |
84 | struct timestamp *second; | 121 | struct timestamp *second; |
85 | 122 | ||
123 | if (first->cpu == avoid_cpu || | ||
124 | (only_cpu != -1 && first->cpu != only_cpu)) { | ||
125 | avoided++; | ||
126 | return; | ||
127 | } | ||
128 | |||
86 | second = find_second_ts(first, end); | 129 | second = find_second_ts(first, end); |
87 | if (second) { | 130 | if (second) { |
88 | if (second->timestamp - first->timestamp > threshold) | 131 | if (second->timestamp - first->timestamp > threshold) |
@@ -91,45 +134,40 @@ static void show_csv(struct timestamp* first, struct timestamp *end) | |||
91 | second->task_type != TSK_RT && !want_best_effort) | 134 | second->task_type != TSK_RT && !want_best_effort) |
92 | non_rt++; | 135 | non_rt++; |
93 | else { | 136 | else { |
94 | printf("%llu, %llu, %llu\n", | 137 | format_pair(first, second); |
95 | (unsigned long long) first->timestamp, | ||
96 | (unsigned long long) second->timestamp, | ||
97 | (unsigned long long) | ||
98 | (second->timestamp - first->timestamp)); | ||
99 | complete++; | 138 | complete++; |
100 | } | 139 | } |
101 | } else | 140 | } else |
102 | incomplete++; | 141 | incomplete++; |
103 | |||
104 | } | 142 | } |
105 | 143 | ||
106 | static inline uint64_t bget(int x, uint64_t quad) | 144 | typedef void (*single_fmt_t)(struct timestamp* ts); |
107 | 145 | ||
146 | static void print_single_csv(struct timestamp* ts) | ||
108 | { | 147 | { |
109 | return (((0xffll << 8 * x) & quad) >> 8 * x); | 148 | printf("0, 0, %llu\n", |
149 | (unsigned long long) (ts->timestamp)); | ||
110 | } | 150 | } |
111 | 151 | ||
112 | static inline uint64_t bput(uint64_t b, int pos) | 152 | static void print_single_bin(struct timestamp* ts) |
113 | { | 153 | { |
114 | return (b << 8 * pos); | 154 | float delta = ts->timestamp; |
115 | } | ||
116 | 155 | ||
117 | static inline uint64_t ntohx(uint64_t q) | 156 | fwrite(&delta, sizeof(delta), 1, stdout); |
118 | { | ||
119 | return (bput(bget(0, q), 7) | bput(bget(1, q), 6) | | ||
120 | bput(bget(2, q), 5) | bput(bget(3, q), 4) | | ||
121 | bput(bget(4, q), 3) | bput(bget(5, q), 2) | | ||
122 | bput(bget(6, q), 1) | bput(bget(7, q), 0)); | ||
123 | } | 157 | } |
124 | 158 | ||
125 | static void restore_byte_order(struct timestamp* start, struct timestamp* end) | 159 | single_fmt_t single_fmt = print_single_csv; |
160 | |||
161 | static void show_single(struct timestamp* ts) | ||
126 | { | 162 | { |
127 | struct timestamp* pos = start; | 163 | if (ts->cpu == avoid_cpu || |
128 | while (pos !=end) { | 164 | (only_cpu != -1 && ts->cpu != only_cpu)) { |
129 | pos->timestamp = ntohx(pos->timestamp); | 165 | avoided++; |
130 | pos->seq_no = ntohl(pos->seq_no); | 166 | } else if (ts->task_type == TSK_RT) { |
131 | pos++; | 167 | single_fmt(ts); |
132 | } | 168 | complete++; |
169 | } else | ||
170 | non_rt++; | ||
133 | } | 171 | } |
134 | 172 | ||
135 | static void show_id(struct timestamp* start, struct timestamp* end, | 173 | static void show_id(struct timestamp* start, struct timestamp* end, |
@@ -145,12 +183,22 @@ static void show_id(struct timestamp* start, struct timestamp* end, | |||
145 | show_csv(start, end); | 183 | show_csv(start, end); |
146 | } | 184 | } |
147 | 185 | ||
148 | #define USAGE \ | 186 | static void show_single_records(struct timestamp* start, struct timestamp* end, |
149 | "Usage: ft2csv [-e] [-i] [-b] <event_name> <logfile> \n" \ | 187 | unsigned long id) |
150 | " -e: endianess swap -- restores byte order \n" \ | 188 | { |
151 | " -i: ignore interleaved -- ignore samples if start " \ | 189 | for (; start != end; start++) |
152 | "and end are non-consecutive\n" \ | 190 | if (start->event == id) |
191 | show_single(start); | ||
192 | } | ||
193 | |||
194 | #define USAGE \ | ||
195 | "Usage: ft2csv [-r] [-i] [-b] [-a CPU] [-o CPU] <event_name> <logfile> \n" \ | ||
196 | " -i: ignore interleaved -- ignore samples if start " \ | ||
197 | "and end are non-consecutive\n" \ | ||
153 | " -b: best effort -- don't skip non-rt time stamps \n" \ | 198 | " -b: best effort -- don't skip non-rt time stamps \n" \ |
199 | " -r: raw binary format -- don't produce .csv output \n" \ | ||
200 | " -a: avoid CPU -- skip samples from a specific CPU\n" \ | ||
201 | " -o: only CPU -- skip all samples from other CPUs\n" \ | ||
154 | "" | 202 | "" |
155 | 203 | ||
156 | static void die(char* msg) | 204 | static void die(char* msg) |
@@ -162,7 +210,7 @@ static void die(char* msg) | |||
162 | exit(1); | 210 | exit(1); |
163 | } | 211 | } |
164 | 212 | ||
165 | #define OPTS "eib" | 213 | #define OPTS "ibra:o:" |
166 | 214 | ||
167 | int main(int argc, char** argv) | 215 | int main(int argc, char** argv) |
168 | { | 216 | { |
@@ -170,21 +218,35 @@ int main(int argc, char** argv) | |||
170 | size_t size, count; | 218 | size_t size, count; |
171 | struct timestamp *ts, *end; | 219 | struct timestamp *ts, *end; |
172 | cmd_t id; | 220 | cmd_t id; |
173 | int swap_byte_order = 0; | ||
174 | int opt; | 221 | int opt; |
175 | char event_name[80]; | 222 | char event_name[80]; |
176 | 223 | ||
177 | while ((opt = getopt(argc, argv, OPTS)) != -1) { | 224 | while ((opt = getopt(argc, argv, OPTS)) != -1) { |
178 | switch (opt) { | 225 | switch (opt) { |
179 | case 'e': | ||
180 | swap_byte_order = 1; | ||
181 | break; | ||
182 | case 'i': | 226 | case 'i': |
183 | want_interleaved = 0; | 227 | want_interleaved = 0; |
228 | fprintf(stderr, "Discarging interleaved samples.\n"); | ||
184 | break; | 229 | break; |
185 | case 'b': | 230 | case 'b': |
231 | fprintf(stderr,"Not filtering samples from best-effort" | ||
232 | " tasks.\n"); | ||
186 | want_best_effort = 1; | 233 | want_best_effort = 1; |
187 | break; | 234 | break; |
235 | case 'r': | ||
236 | fprintf(stderr, "Generating binary (raw) output.\n"); | ||
237 | single_fmt = print_single_bin; | ||
238 | format_pair = print_pair_bin; | ||
239 | break; | ||
240 | case 'a': | ||
241 | avoid_cpu = atoi(optarg); | ||
242 | fprintf(stderr, "Disarding all samples from CPU %d.\n", | ||
243 | avoid_cpu); | ||
244 | break; | ||
245 | case 'o': | ||
246 | only_cpu = atoi(optarg); | ||
247 | fprintf(stderr, "Using only samples from CPU %d.\n", | ||
248 | only_cpu); | ||
249 | break; | ||
188 | default: | 250 | default: |
189 | die("Unknown option."); | 251 | die("Unknown option."); |
190 | break; | 252 | break; |
@@ -208,20 +270,22 @@ int main(int argc, char** argv) | |||
208 | count = size / sizeof(struct timestamp); | 270 | count = size / sizeof(struct timestamp); |
209 | end = ts + count; | 271 | end = ts + count; |
210 | 272 | ||
211 | if (swap_byte_order) | 273 | if (id >= SINGLE_RECORDS_RANGE) |
212 | restore_byte_order(ts, end); | 274 | show_single_records(ts, end, id); |
213 | show_id(ts, end, id); | 275 | else |
276 | show_id(ts, end, id); | ||
214 | 277 | ||
215 | fprintf(stderr, | 278 | fprintf(stderr, |
216 | "Total : %10d\n" | 279 | "Total : %10d\n" |
217 | "Skipped : %10d\n" | 280 | "Skipped : %10d\n" |
281 | "Avoided : %10d\n" | ||
218 | "Complete : %10d\n" | 282 | "Complete : %10d\n" |
219 | "Incomplete : %10d\n" | 283 | "Incomplete : %10d\n" |
220 | "Filtered : %10d\n" | 284 | "Filtered : %10d\n" |
221 | "Non RT : %10d\n" | 285 | "Non RT : %10d\n" |
222 | "Interleaved : %10d\n", | 286 | "Interleaved : %10d\n", |
223 | (int) count, | 287 | (int) count, |
224 | skipped, complete, | 288 | skipped, avoided, complete, |
225 | incomplete, filtered, non_rt, | 289 | incomplete, filtered, non_rt, |
226 | interleaved); | 290 | interleaved); |
227 | 291 | ||