aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBjoern Brandenburg <bbb@mpi-sws.org>2012-08-15 10:14:52 -0400
committerBjoern Brandenburg <bbb@mpi-sws.org>2012-10-19 16:38:25 -0400
commit44da17bf24f2e67ab71ecb552ebf7b460e64999e (patch)
tree2d23a65de5a5c095f2d18c2f2fad0c688de9a49f /src
parent2265873941ade09b9ba4eb754278818cd5801d3a (diff)
Support matching based on PID in ft2csv
Diffstat (limited to 'src')
-rw-r--r--src/ft2csv.c140
1 files changed, 126 insertions, 14 deletions
diff --git a/src/ft2csv.c b/src/ft2csv.c
index a6b1bf2..ff3db23 100644
--- a/src/ft2csv.c
+++ b/src/ft2csv.c
@@ -27,8 +27,11 @@
27 27
28#include "timestamp.h" 28#include "timestamp.h"
29 29
30#define AUTO_SELECT -1
31
30static int want_interleaved = 1; 32static int want_interleaved = 1;
31static int want_best_effort = 0; 33static int want_best_effort = 0;
34static int find_by_pid = AUTO_SELECT;
32 35
33/* discard samples from a specific CPU */ 36/* discard samples from a specific CPU */
34static int avoid_cpu = -1; 37static int avoid_cpu = -1;
@@ -94,48 +97,146 @@ static struct timestamp* find_second_ts(struct timestamp* start,
94 start->event); 97 start->event);
95} 98}
96 99
97typedef void (*pair_fmt_t)(struct timestamp* first, struct timestamp* second); 100static struct timestamp* next_pid(struct timestamp* start, struct timestamp* end,
101 unsigned int pid, unsigned long id1, unsigned long id2)
102{
103 struct timestamp* pos;
104 unsigned int last_seqno = 0;
105
106 for (pos = start; pos != end; pos++) {
107 /* check for for holes in the sequence number */
108 if (last_seqno && last_seqno + 1 != pos->seq_no) {
109 /* stumbled across a hole */
110 return NULL;
111 }
112 last_seqno = pos->seq_no;
113
114 /* only care about this PID */
115 if (pos->pid == pid) {
116 /* is it the right one? */
117 if (pos->event == id1 || pos->event == id2)
118 return pos;
119 else
120 /* Don't allow unexptected IDs interleaved.
121 * Tasks are sequential, there shouldn't be
122 * anything else. */
123 return NULL;
124 }
125 }
126 return NULL;
127}
98 128
99static void print_pair_csv(struct timestamp* first, struct timestamp* second) 129static struct timestamp* accumulate_exec_time(
130 struct timestamp* start, struct timestamp* end,
131 unsigned int pid, unsigned long stop_id, uint64_t *sum)
132{
133 struct timestamp* pos = start;
134 uint64_t exec_start;
135
136 *sum = 0;
137
138 while (1) {
139 exec_start = pos->timestamp;
140
141 /* find a suspension */
142 pos = next_pid(pos + 1, end, pid, TS_LOCK_SUSPEND, stop_id);
143 if (!pos)
144 /* broken stream */
145 return NULL;
146
147 /* account for exec until pos */
148 *sum += pos->timestamp - exec_start;
149
150 if (pos->event == stop_id)
151 /* no suspension */
152 return pos;
153
154 /* find matching resume */
155 pos = next_pid(pos + 1, end, pid, TS_LOCK_RESUME, 0);
156 if (!pos)
157 /* broken stream */
158 return NULL;
159
160 /* must be a resume => start over */
161 }
162}
163
164typedef void (*pair_fmt_t)(struct timestamp* first, struct timestamp* second, uint64_t exec_time);
165
166static void print_pair_csv(struct timestamp* first, struct timestamp* second, uint64_t exec_time)
100{ 167{
101 printf("%llu, %llu, %llu\n", 168 printf("%llu, %llu, %llu\n",
102 (unsigned long long) first->timestamp, 169 (unsigned long long) first->timestamp,
103 (unsigned long long) second->timestamp, 170 (unsigned long long) second->timestamp,
104 (unsigned long long) 171 (unsigned long long) exec_time);
105 (second->timestamp - first->timestamp));
106} 172}
107 173
108static void print_pair_bin(struct timestamp* first, struct timestamp* second) 174static void print_pair_bin(struct timestamp* first, struct timestamp* second, uint64_t exec_time)
109{ 175{
110 float delta = second->timestamp - first->timestamp; 176 float delta = exec_time;
111 fwrite(&delta, sizeof(delta), 1, stdout); 177 fwrite(&delta, sizeof(delta), 1, stdout);
112} 178}
113 179
114pair_fmt_t format_pair = print_pair_csv; 180pair_fmt_t format_pair = print_pair_csv;
115 181
116static void show_csv(struct timestamp* first, struct timestamp *end) 182static void find_event_by_pid(struct timestamp* first, struct timestamp* end)
117{ 183{
118 struct timestamp *second; 184 struct timestamp *second;
119 185 uint64_t exec_time = 0;
120 if (first->cpu == avoid_cpu || 186
121 (only_cpu != -1 && first->cpu != only_cpu)) { 187 /* special case: take suspensions into account */
122 avoided++; 188 if (first->event >= SUSPENSION_RANGE) {
123 return; 189 second = accumulate_exec_time(first, end,
190 first->pid,
191 first->event + 1, &exec_time);
192 } else {
193 second = next_pid(first + 1, end, first->pid,
194 first->event + 1, 0);
195 if (second)
196 exec_time = second->timestamp - first->timestamp;
124 } 197 }
198 if (second) {
199 format_pair(first, second, exec_time);
200 complete++;
201 } else
202 incomplete++;
203}
204
205static void find_event_by_eid(struct timestamp *first, struct timestamp* end)
206{
207 struct timestamp *second;
208 uint64_t exec_time;
125 209
126 second = find_second_ts(first, end); 210 second = find_second_ts(first, end);
127 if (second) { 211 if (second) {
212 exec_time = second->timestamp - first->timestamp;
128 if (first->task_type != TSK_RT && 213 if (first->task_type != TSK_RT &&
129 second->task_type != TSK_RT && !want_best_effort) 214 second->task_type != TSK_RT && !want_best_effort)
130 non_rt++; 215 non_rt++;
131 else { 216 else {
132 format_pair(first, second); 217 format_pair(first, second, exec_time);
133 complete++; 218 complete++;
134 } 219 }
135 } else 220 } else
136 incomplete++; 221 incomplete++;
137} 222}
138 223
224static void show_csv(struct timestamp* first, struct timestamp *end)
225{
226
227
228 if (first->cpu == avoid_cpu ||
229 (only_cpu != -1 && first->cpu != only_cpu)) {
230 avoided++;
231 return;
232 }
233
234 if (find_by_pid)
235 find_event_by_pid(first, end);
236 else
237 find_event_by_eid(first, end);
238}
239
139typedef void (*single_fmt_t)(struct timestamp* ts); 240typedef void (*single_fmt_t)(struct timestamp* ts);
140 241
141static void print_single_csv(struct timestamp* ts) 242static void print_single_csv(struct timestamp* ts)
@@ -205,7 +306,7 @@ static void die(char* msg)
205 exit(1); 306 exit(1);
206} 307}
207 308
208#define OPTS "ibra:o:" 309#define OPTS "ibra:o:pe"
209 310
210int main(int argc, char** argv) 311int main(int argc, char** argv)
211{ 312{
@@ -242,6 +343,14 @@ int main(int argc, char** argv)
242 fprintf(stderr, "Using only samples from CPU %d.\n", 343 fprintf(stderr, "Using only samples from CPU %d.\n",
243 only_cpu); 344 only_cpu);
244 break; 345 break;
346 case 'p':
347 find_by_pid = 1;
348 fprintf(stderr, "Matching timestamp pairs based on PID.\n");
349 break;
350 case 'e':
351 find_by_pid = 0;
352 fprintf(stderr, "Matching timestamp pairs based on event ID.\n");
353 break;
245 default: 354 default:
246 die("Unknown option."); 355 die("Unknown option.");
247 break; 356 break;
@@ -261,6 +370,9 @@ int main(int argc, char** argv)
261 die("Unknown event!"); 370 die("Unknown event!");
262 } 371 }
263 372
373 if (find_by_pid == AUTO_SELECT)
374 find_by_pid = id <= PID_RECORDS_RANGE;
375
264 ts = (struct timestamp*) mapped; 376 ts = (struct timestamp*) mapped;
265 count = size / sizeof(struct timestamp); 377 count = size / sizeof(struct timestamp);
266 end = ts + count; 378 end = ts + count;