aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2011-07-25 18:48:04 -0400
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2011-07-25 18:48:04 -0400
commit38f0c2047819574a120380810de77c79c2a61bee (patch)
tree12ba5fd7271a50d14a901f5f759766cc057a113f
parent784e08135bc3d68f9c3fe02ba32e2e4711d8fcc6 (diff)
correctly handle PID timestamps
And account for suspension time.
-rw-r--r--src/ft2csv.c129
1 files changed, 115 insertions, 14 deletions
diff --git a/src/ft2csv.c b/src/ft2csv.c
index aceeb25..75c9f35 100644
--- a/src/ft2csv.c
+++ b/src/ft2csv.c
@@ -97,50 +97,151 @@ static struct timestamp* find_second_ts(struct timestamp* start,
97 start->event); 97 start->event);
98} 98}
99 99
100typedef 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 (ts_pid_fragment(pos) == 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}
128
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);
101 165
102static void print_pair_csv(struct timestamp* first, struct timestamp* second) 166static void print_pair_csv(struct timestamp* first, struct timestamp* second, uint64_t exec_time)
103{ 167{
104 printf("%llu, %llu, %llu\n", 168 printf("%llu, %llu, %llu\n",
105 (unsigned long long) first->timestamp, 169 (unsigned long long) first->timestamp,
106 (unsigned long long) second->timestamp, 170 (unsigned long long) second->timestamp,
107 (unsigned long long) 171 (unsigned long long) exec_time);
108 (second->timestamp - first->timestamp));
109} 172}
110 173
111static 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)
112{ 175{
113 float delta = second->timestamp - first->timestamp; 176 float delta = exec_time;
114 fwrite(&delta, sizeof(delta), 1, stdout); 177 fwrite(&delta, sizeof(delta), 1, stdout);
115} 178}
116 179
117pair_fmt_t format_pair = print_pair_csv; 180pair_fmt_t format_pair = print_pair_csv;
118 181
119static void show_csv(struct timestamp* first, struct timestamp *end) 182static void find_event_by_pid(struct timestamp* first, struct timestamp* end)
120{ 183{
121 struct timestamp *second; 184 struct timestamp *second;
122 185 uint64_t exec_time = 0;
123 if (first->cpu == avoid_cpu || 186
124 (only_cpu != -1 && first->cpu != only_cpu)) { 187 /* special case: take suspensions into account */
125 avoided++; 188 if (first->event == TS_LOCK_START) {
126 return; 189 second = accumulate_exec_time(first, end,
190 ts_pid_fragment(first),
191 first->event + 3, &exec_time);
192 } else {
193 second = next_pid(first + 1, end, ts_pid_fragment(first),
194 first->event + 1, 0);
195 if (second)
196 exec_time = second->timestamp - first->timestamp;
127 } 197 }
198 if (second) {
199 if (exec_time > threshold)
200 filtered++;
201 else
202 format_pair(first, second, exec_time);
203 complete++;
204 } else
205 incomplete++;
206}
207
208static void find_event_by_eid(struct timestamp *first, struct timestamp* end)
209{
210 struct timestamp *second;
211 uint64_t exec_time;
128 212
129 second = find_second_ts(first, end); 213 second = find_second_ts(first, end);
130 if (second) { 214 if (second) {
131 if (second->timestamp - first->timestamp > threshold) 215 exec_time = second->timestamp - first->timestamp;
216 if (exec_time > threshold)
132 filtered++; 217 filtered++;
133 else if (first->task_type != TSK_RT && 218 else if (first->task_type != TSK_RT &&
134 second->task_type != TSK_RT && !want_best_effort) 219 second->task_type != TSK_RT && !want_best_effort)
135 non_rt++; 220 non_rt++;
136 else { 221 else {
137 format_pair(first, second); 222 format_pair(first, second, exec_time);
138 complete++; 223 complete++;
139 } 224 }
140 } else 225 } else
141 incomplete++; 226 incomplete++;
142} 227}
143 228
229static void show_csv(struct timestamp* first, struct timestamp *end)
230{
231
232
233 if (first->cpu == avoid_cpu ||
234 (only_cpu != -1 && first->cpu != only_cpu)) {
235 avoided++;
236 return;
237 }
238
239 if (first->event <= PID_RECORDS_RANGE)
240 find_event_by_pid(first, end);
241 else
242 find_event_by_eid(first, end);
243}
244
144typedef void (*single_fmt_t)(struct timestamp* ts); 245typedef void (*single_fmt_t)(struct timestamp* ts);
145 246
146static void print_single_csv(struct timestamp* ts) 247static void print_single_csv(struct timestamp* ts)