aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ft2csv.c195
-rw-r--r--src/timestamp.c6
2 files changed, 176 insertions, 25 deletions
diff --git a/src/ft2csv.c b/src/ft2csv.c
index a6b1bf2..b75b284 100644
--- a/src/ft2csv.c
+++ b/src/ft2csv.c
@@ -41,8 +41,14 @@ static unsigned int skipped = 0;
41static unsigned int non_rt = 0; 41static unsigned int non_rt = 0;
42static unsigned int interleaved = 0; 42static unsigned int interleaved = 0;
43static unsigned int avoided = 0; 43static unsigned int avoided = 0;
44static unsigned int lvl_a_sched = 0;
45static unsigned int lvl_b_sched = 0;
46static unsigned int lvl_c_sched = 0;
47static unsigned int other_sched = 0;
48static unsigned int filtered = 0;
44 49
45#define CYCLES_PER_US 2128 50#define CYCLES_PER_US 2128
51static unsigned long long threshold = CYCLES_PER_US * 10000; /* 10 ms == 10 full ticks */
46 52
47static struct timestamp* next(struct timestamp* start, struct timestamp* end, 53static struct timestamp* next(struct timestamp* start, struct timestamp* end,
48 int cpu) 54 int cpu)
@@ -94,48 +100,180 @@ static struct timestamp* find_second_ts(struct timestamp* start,
94 start->event); 100 start->event);
95} 101}
96 102
97typedef void (*pair_fmt_t)(struct timestamp* first, struct timestamp* second); 103static struct timestamp* next_pid(struct timestamp* start, struct timestamp* end,
104 unsigned int pid, unsigned long id1, unsigned long id2)
105{
106 struct timestamp* pos;
107 unsigned int last_seqno = 0;
108
109 for (pos = start; pos != end; pos++) {
110 /* check for for holes in the sequence number */
111 if (last_seqno && last_seqno + 1 != pos->seq_no) {
112 /* stumbled across a hole */
113 return NULL;
114 }
115 last_seqno = pos->seq_no;
116
117 /* only care about this PID */
118 if (ts_pid_fragment(pos) == pid) {
119 /* is it the right one? */
120 if (pos->event == id1 || pos->event == id2)
121 return pos;
122 else
123 /* Don't allow unexptected IDs interleaved.
124 * Tasks are sequential, there shouldn't be
125 * anything else. */
126 return NULL;
127 }
128 }
129 return NULL;
130}
131
132static struct timestamp* accumulate_exec_time(
133 struct timestamp* start, struct timestamp* end,
134 unsigned int pid, unsigned long stop_id, uint64_t *sum)
135{
136 struct timestamp* pos = start;
137 uint64_t exec_start;
138
139 *sum = 0;
140
141 while (1) {
142 exec_start = pos->timestamp;
143
144 /* find a suspension */
145 pos = next_pid(pos + 1, end, pid, TS_LOCK_SUSPEND, stop_id);
146 if (!pos)
147 /* broken stream */
148 return NULL;
149
150 /* account for exec until pos */
151 *sum += pos->timestamp - exec_start;
152
153 if (pos->event == stop_id)
154 /* no suspension */
155 return pos;
156
157 /* find matching resume */
158 pos = next_pid(pos + 1, end, pid, TS_LOCK_RESUME, 0);
159 if (!pos)
160 /* broken stream */
161 return NULL;
162
163 /* must be a resume => start over */
164 }
165}
166
167typedef void (*pair_fmt_t)(struct timestamp* first, struct timestamp* second, uint64_t exec_time);
98 168
99static void print_pair_csv(struct timestamp* first, struct timestamp* second) 169static void print_pair_csv(struct timestamp* first, struct timestamp* second, uint64_t exec_time)
100{ 170{
101 printf("%llu, %llu, %llu\n", 171 printf("%llu, %llu, %llu\n",
102 (unsigned long long) first->timestamp, 172 (unsigned long long) first->timestamp,
103 (unsigned long long) second->timestamp, 173 (unsigned long long) second->timestamp,
104 (unsigned long long) 174 (unsigned long long) exec_time);
105 (second->timestamp - first->timestamp));
106} 175}
107 176
108static void print_pair_bin(struct timestamp* first, struct timestamp* second) 177static void print_pair_bin(struct timestamp* first, struct timestamp* second, uint64_t exec_time)
109{ 178{
110 float delta = second->timestamp - first->timestamp; 179 float delta = exec_time;
111 fwrite(&delta, sizeof(delta), 1, stdout); 180 fwrite(&delta, sizeof(delta), 1, stdout);
112} 181}
113 182
114pair_fmt_t format_pair = print_pair_csv; 183pair_fmt_t format_pair = print_pair_csv;
115 184
116static void show_csv(struct timestamp* first, struct timestamp *end) 185static void find_event_by_pid(struct timestamp* first, struct timestamp* end)
117{ 186{
118 struct timestamp *second; 187 struct timestamp *second;
119 188 uint64_t exec_time = 0;
120 if (first->cpu == avoid_cpu || 189
121 (only_cpu != -1 && first->cpu != only_cpu)) { 190 /* special case: take suspensions into account */
122 avoided++; 191 if (first->event == TS_LOCK_START) {
123 return; 192 second = accumulate_exec_time(first, end,
193 ts_pid_fragment(first),
194 first->event + 3, &exec_time);
195 } else {
196 second = next_pid(first + 1, end, ts_pid_fragment(first),
197 first->event + 1, 0);
198 if (second)
199 exec_time = second->timestamp - first->timestamp;
124 } 200 }
201 if (second) {
202 if (exec_time > threshold)
203 filtered++;
204 else
205 format_pair(first, second, exec_time);
206 complete++;
207 } else
208 incomplete++;
209}
210
211static void find_event_by_eid(struct timestamp *first, struct timestamp* end)
212{
213 struct timestamp *second;
214 uint64_t exec_time;
125 215
126 second = find_second_ts(first, end); 216 second = find_second_ts(first, end);
127 if (second) { 217 if (second) {
128 if (first->task_type != TSK_RT && 218 exec_time = second->timestamp - first->timestamp;
219 if (exec_time > threshold)
220 filtered++;
221 else if (first->task_type != TSK_RT &&
129 second->task_type != TSK_RT && !want_best_effort) 222 second->task_type != TSK_RT && !want_best_effort)
130 non_rt++; 223 {
131 else { 224 if (TS_LVLA_SCHED_END == second->event &&
132 format_pair(first, second); 225 second->task_type == TSK_LVLA)
226 {
227 format_pair(first, second, exec_time);
228 complete++;
229 lvl_a_sched++;
230 } else if (TS_LVLB_SCHED_END == second->event &&
231 second->task_type == TSK_LVLB)
232 {
233 format_pair(first, second, exec_time);
234 complete++;
235 lvl_b_sched++;
236 } else if (TS_LVLC_SCHED_END == second->event &&
237 second->task_type == TSK_LVLC)
238 {
239 format_pair(first, second, exec_time);
240 complete++;
241 lvl_c_sched++;
242
243 } else {
244 non_rt++;
245 }
246 } else if ((TS_LVLA_SCHED_END == second->event ||
247 TS_LVLB_SCHED_END == second->event ||
248 TS_LVLC_SCHED_END == second->event) &&
249 TSK_RT == second->task_type)
250 {
251 other_sched++;
252 } else
253 {
254 format_pair(first, second, exec_time);
133 complete++; 255 complete++;
134 } 256 }
135 } else 257 } else
136 incomplete++; 258 incomplete++;
137} 259}
138 260
261static void show_csv(struct timestamp* first, struct timestamp *end)
262{
263
264
265 if (first->cpu == avoid_cpu ||
266 (only_cpu != -1 && first->cpu != only_cpu)) {
267 avoided++;
268 return;
269 }
270
271 if (first->event <= PID_RECORDS_RANGE)
272 find_event_by_pid(first, end);
273 else
274 find_event_by_eid(first, end);
275}
276
139typedef void (*single_fmt_t)(struct timestamp* ts); 277typedef void (*single_fmt_t)(struct timestamp* ts);
140 278
141static void print_single_csv(struct timestamp* ts) 279static void print_single_csv(struct timestamp* ts)
@@ -271,17 +409,24 @@ int main(int argc, char** argv)
271 show_id(ts, end, id); 409 show_id(ts, end, id);
272 410
273 fprintf(stderr, 411 fprintf(stderr,
274 "Total : %10d\n" 412 "Total : %10d\n"
275 "Skipped : %10d\n" 413 "Skipped : %10d\n"
276 "Avoided : %10d\n" 414 "Avoided : %10d\n"
277 "Complete : %10d\n" 415 "Complete : %10d\n"
278 "Incomplete : %10d\n" 416 "Incomplete : %10d\n"
279 "Non RT : %10d\n" 417 "Filtered : %10d\n"
280 "Interleaved : %10d\n", 418 "Non RT : %10d\n"
419 "Interleaved : %10d\n"
420 "Lvl-A Sched : %10d\n"
421 "Lvl-B Sched : %10d\n"
422 "Lvl-C Sched : %10d\n"
423 "Other Sched (non-A) : %10d\n",
281 (int) count, 424 (int) count,
282 skipped, avoided, complete, 425 skipped, avoided, complete,
283 incomplete, non_rt, 426 incomplete, filtered, non_rt,
284 interleaved); 427 interleaved, lvl_a_sched, lvl_b_sched, lvl_c_sched,
428 other_sched);
429
285 430
286 return 0; 431 return 0;
287} 432}
diff --git a/src/timestamp.c b/src/timestamp.c
index 442c445..cad3fb5 100644
--- a/src/timestamp.c
+++ b/src/timestamp.c
@@ -22,6 +22,12 @@ static struct event_name event_table[] =
22 EVENT(PLUGIN_TICK), 22 EVENT(PLUGIN_TICK),
23 EVENT(CXS), 23 EVENT(CXS),
24 EVENT(SEND_RESCHED), 24 EVENT(SEND_RESCHED),
25 EVENT(LVLA_RELEASE),
26 EVENT(LVLA_SCHED),
27 EVENT(LVLB_RELEASE),
28 EVENT(LVLB_SCHED),
29 EVENT(LVLC_RELEASE),
30 EVENT(LVLC_SCHED),
25 {"RELEASE_LATENCY", TS_RELEASE_LATENCY}, 31 {"RELEASE_LATENCY", TS_RELEASE_LATENCY},
26 32
27 EVENT(SYSCALL_IN), 33 EVENT(SYSCALL_IN),