| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2011 The Chromium OS Authors. All rights reserved. | 2 * Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
| 3 * Distributed under the terms of the GNU General Public License v2 | 3 * Distributed under the terms of the GNU General Public License v2 |
| 4 */ | 4 */ |
| 5 | 5 |
| 6 #include <pthread.h> | 6 #include <pthread.h> |
| 7 #include <stdio.h> | 7 #include <stdio.h> |
| 8 #include <stdlib.h> | 8 #include <stdlib.h> |
| 9 #include <string.h> | 9 #include <string.h> |
| 10 #include <unistd.h> | 10 #include <unistd.h> |
| 11 | 11 |
| 12 #include <sys/types.h> | 12 #include <sys/types.h> |
| 13 #include <sys/stat.h> | 13 #include <sys/stat.h> |
| 14 #include <fcntl.h> | 14 #include <fcntl.h> |
| 15 | 15 |
| 16 #include <debug.h> |
| 16 #include <eprintf.h> | 17 #include <eprintf.h> |
| 18 #include <mylib.h> |
| 17 #include <style.h> | 19 #include <style.h> |
| 18 | 20 |
| 21 #include "collector.h" |
| 22 #include "ktop.h" |
| 19 #include "syscall.h" | 23 #include "syscall.h" |
| 20 #include "ktop.h" | |
| 21 | 24 |
| 22 #define _STR(x) #x | 25 #define _STR(x) #x |
| 23 #define STR(x) _STR(x) | 26 #define STR(x) _STR(x) |
| 24 #define MAX_PATH 256 | 27 #define MAX_PATH 256 |
| 25 | 28 |
| 26 enum {» BUF_SIZE = 1 << 12, | 29 enum { PIDCALL_BUCKETS = 1543 }; |
| 27 » SMALL_READ = BUF_SIZE >> 2 }; | |
| 28 | |
| 29 typedef struct ring_header_s { | |
| 30 » u64» time_stamp; | |
| 31 » unint» commit; | |
| 32 » u8» data[]; | |
| 33 } ring_header_s; | |
| 34 | |
| 35 typedef struct ring_event_s { | |
| 36 » u32» type_len : 5, | |
| 37 » » time_delta : 27; | |
| 38 » u32» array[]; | |
| 39 } ring_event_s; | |
| 40 | |
| 41 typedef struct event_s { | |
| 42 » u16» type; | |
| 43 » u8» flags; | |
| 44 » u8» preempt_count; | |
| 45 » s32» pid; | |
| 46 » s32» lock_depth; | |
| 47 } event_s; | |
| 48 | |
| 49 typedef struct sys_enter_s { | |
| 50 » event_s»ev; | |
| 51 » snint» id; | |
| 52 » unint» args[6]; | |
| 53 } sys_enter_s; | |
| 54 | |
| 55 typedef struct sys_exit_s { | |
| 56 » event_s»ev; | |
| 57 » snint» id; | |
| 58 » snint» ret; | |
| 59 } sys_exit_s; | |
| 60 | |
| 61 | 30 |
| 62 pthread_mutex_t Count_lock = PTHREAD_MUTEX_INITIALIZER; | 31 pthread_mutex_t Count_lock = PTHREAD_MUTEX_INITIALIZER; |
| 63 | 32 |
| 64 u64 Syscall_count[NUM_SYS_CALLS]; | 33 u64 Syscall_count[NUM_SYS_CALLS]; |
| 65 u64 MyPidCount; | 34 u64 MyPidCount; |
| 66 u64 Slept; | 35 u64 Slept; |
| 67 int Pid[MAX_PID]; | 36 int Pid[MAX_PID]; |
| 68 | 37 |
| 38 Pidcall_s Pidcall[MAX_PIDCALLS]; |
| 39 Pidcall_s *Pidclock = Pidcall; |
| 40 u64 PidcallIterations; |
| 41 u64 PidcallRecord; |
| 42 u64 Pidcall_tick; |
| 43 |
| 44 u64 No_enter; |
| 45 u64 Found; |
| 46 u64 Out_of_order; |
| 47 u64 No_start; |
| 48 |
| 49 Pidcall_s *Pidcall_bucket[PIDCALL_BUCKETS]; |
| 50 |
| 69 static const char *find_debugfs(void) | 51 static const char *find_debugfs(void) |
| 70 { | 52 { |
| 71 static char debugfs[MAX_PATH+1]; | 53 static char debugfs[MAX_PATH+1]; |
| 72 static int debugfs_found; | 54 static int debugfs_found; |
| 73 char type[100]; | 55 char type[100]; |
| 74 FILE *fp; | 56 FILE *fp; |
| 75 | 57 |
| 76 if (debugfs_found) | 58 if (debugfs_found) |
| 77 return debugfs; | 59 return debugfs; |
| 78 | 60 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 162 { | 144 { |
| 163 | 145 |
| 164 enable_event("sys_exit"); | 146 enable_event("sys_exit"); |
| 165 } | 147 } |
| 166 | 148 |
| 167 static void disable_sys_exit (void) | 149 static void disable_sys_exit (void) |
| 168 { | 150 { |
| 169 disable_event("sys_exit"); | 151 disable_event("sys_exit"); |
| 170 } | 152 } |
| 171 | 153 |
| 172 static int init_raw(int cpu) | 154 int open_raw(int cpu) |
| 173 { | 155 { |
| 174 char name[MAX_NAME]; | 156 char name[MAX_NAME]; |
| 175 int fd; | 157 int fd; |
| 176 | 158 |
| 177 snprintf(name, sizeof(name), "per_cpu/cpu%d/trace_pipe_raw", cpu); | 159 snprintf(name, sizeof(name), "per_cpu/cpu%d/trace_pipe_raw", cpu); |
| 178 fd = open(tracing_file(name), O_RDONLY); | 160 fd = open(tracing_file(name), O_RDONLY); |
| 179 if (fd == -1) { | 161 if (fd == -1) { |
| 180 fatal("open %s:", name); | 162 fatal("open %s:", name); |
| 181 } | 163 } |
| 182 return fd; | 164 return fd; |
| 183 } | 165 } |
| 184 | 166 |
| 185 Pidcall_s Pidcall[MAX_PIDCALLS]; | 167 static Pidcall_s *hash_pidcall(u32 pidcall) |
| 186 Pidcall_s *Pidnext = Pidcall; | |
| 187 | |
| 188 static inline void swap_pidcall(Pidcall_s *p) | |
| 189 { | 168 { |
| 190 » Pidcall_s tmp; | 169 » return (Pidcall_s *)&Pidcall_bucket[pidcall % PIDCALL_BUCKETS]; |
| 191 | |
| 192 » if (p == Pidcall) return; | |
| 193 » tmp = *p; | |
| 194 » *p = p[-1]; | |
| 195 » p[-1] = tmp; | |
| 196 } | 170 } |
| 197 | 171 |
| 198 void record_pid_syscall (u32 pidcall) | 172 static Pidcall_s *find_pidcall(u32 pidcall) |
| 199 { | 173 { |
| 200 » Pidcall_s *p; | 174 » Pidcall_s *pc = hash_pidcall(pidcall); |
| 201 | 175 |
| 202 » for (p = Pidcall; p < Pidnext; p++) { | 176 ++PidcallRecord; |
| 203 » » if (p->pidcall == pidcall) { | 177 » for (;;) { |
| 204 » » » ++p->count; | 178 ++PidcallIterations; |
| 205 » » » swap_pidcall(p); | 179 » » pc = pc->next; |
| 180 » » if (!pc) return NULL; |
| 181 » » if (pc->pidcall == pidcall) { |
| 182 » » » pc->clock = 1; |
| 183 » » » return pc; |
| 184 » » } |
| 185 » } |
| 186 } |
| 187 |
| 188 #if 0 |
| 189 static void dump(char *label, Pidcall_s *pc) |
| 190 { |
| 191 » int i; |
| 192 |
| 193 » fprintf(stderr, "%s", label); |
| 194 » for (i = 0; (i < 10) && pc; i++) { |
| 195 » » fprintf(stderr, " %p", pc); |
| 196 » » pc = pc->next; |
| 197 » } |
| 198 » if (pc) fprintf(stderr, "STUCK"); |
| 199 » fprintf(stderr, "\n"); |
| 200 } |
| 201 #endif |
| 202 |
| 203 static void add_pidcall(Pidcall_s *pidcall) |
| 204 { |
| 205 » Pidcall_s *pc = hash_pidcall(pidcall->pidcall); |
| 206 |
| 207 » pidcall->next = pc->next; |
| 208 » pc->next = pidcall; |
| 209 } |
| 210 |
| 211 static void rmv_pidcall(u32 pidcall) |
| 212 { |
| 213 » Pidcall_s *prev = hash_pidcall(pidcall); |
| 214 » Pidcall_s *next; |
| 215 |
| 216 » for (;;) { |
| 217 » » next = prev->next; |
| 218 » » if (!next) return; |
| 219 » » if (next->pidcall == pidcall) { |
| 220 » » » prev->next = next->next; |
| 206 return; | 221 return; |
| 207 } | 222 } |
| 223 prev = next; |
| 208 } | 224 } |
| 209 if (Pidnext == &Pidcall[MAX_PIDCALLS]) { | |
| 210 /* | |
| 211 * Need a better method but this might be good enough | |
| 212 */ | |
| 213 --p; | |
| 214 p->pidcall = pidcall; | |
| 215 p->count = 1; | |
| 216 swap_pidcall(p); | |
| 217 return; | |
| 218 } | |
| 219 p = Pidnext++; | |
| 220 p->pidcall = pidcall; | |
| 221 p->count = 1; | |
| 222 } | 225 } |
| 223 | 226 |
| 224 static void process_sys_enter(void *event) | 227 static Pidcall_s *victim_pidcall(u32 pidcall) |
| 228 { |
| 229 » Pidcall_s *pc = Pidclock; |
| 230 |
| 231 » while (pc->clock) { |
| 232 ++Pidcall_tick; |
| 233 » » pc->clock = 0; |
| 234 » » if (++Pidclock == &Pidcall[MAX_PIDCALLS]) { |
| 235 » » » Pidclock = Pidcall; |
| 236 » » } |
| 237 » » pc = Pidclock; |
| 238 » } |
| 239 » if (pc->pidcall) { |
| 240 » » rmv_pidcall(pc->pidcall); |
| 241 » } |
| 242 » if (pc->name) { |
| 243 » » free(pc->name); |
| 244 » } |
| 245 » zero(*pc); |
| 246 » pc->pidcall = pidcall; |
| 247 » add_pidcall(pc); |
| 248 |
| 249 » return pc; |
| 250 } |
| 251 |
| 252 static void parse_sys_enter(void *event, u64 time) |
| 225 { | 253 { |
| 226 sys_enter_s *sy = event; | 254 sys_enter_s *sy = event; |
| 227 » int pid = sy->ev.pid; | 255 » int pid = sy->ev.pid; |
| 228 » snint call_num = sy->id; | 256 » snint call_num = sy->id; |
| 257 » u32 pidcall = mkpidcall(pid, call_num); |
| 258 » Pidcall_s *pc; |
| 229 | 259 |
| 230 ++Pid[pid]; | 260 ++Pid[pid]; |
| 231 | 261 |
| 232 if (call_num >= Num_syscalls) { | 262 if (call_num >= Num_syscalls) { |
| 233 warn("syscall number out of range %ld\n", call_num); | 263 warn("syscall number out of range %ld\n", call_num); |
| 234 return; | 264 return; |
| 235 } | 265 } |
| 236 ++Syscall_count[call_num]; | 266 ++Syscall_count[call_num]; |
| 237 » record_pid_syscall(mkpidcall(pid, call_num)); | 267 |
| 268 » pc = find_pidcall(pidcall); |
| 269 » if (!pc) { |
| 270 » » pc = victim_pidcall(pidcall); |
| 271 » } |
| 272 » ++pc->count; |
| 273 » pc->time.start = time; |
| 274 » memmove(pc->arg, sy->arg, sizeof(pc->arg)); |
| 238 } | 275 } |
| 239 | 276 |
| 240 static void process_sys_exit(void *event) | 277 static void parse_sys_exit(void *event, u64 time) |
| 241 { | 278 { |
| 242 //» sys_exit_s *sy = event; | 279 » sys_exit_s *sy = event; |
| 280 » int pid = sy->ev.pid; |
| 281 » snint call_num = sy->id; |
| 282 » u32 pidcall = mkpidcall(pid, call_num); |
| 283 » Pidcall_s *pc; |
| 284 |
| 285 » pc = find_pidcall(pidcall); |
| 286 » if (!pc) { |
| 287 » » ++No_enter; |
| 288 » » return; |
| 289 » } |
| 290 » if (pc->time.start) { |
| 291 » » if (time > pc->time.start) { |
| 292 » » » ++Found; |
| 293 » » » pc->time.total += time - pc->time.start; |
| 294 » » } else { |
| 295 » » » ++Out_of_order; |
| 296 » » } |
| 297 » » pc->time.start = 0; |
| 298 » } else { |
| 299 » » ++No_start; |
| 300 » } |
| 243 } | 301 } |
| 244 | 302 |
| 245 static void process_event(void *buf) | 303 static void parse_event(void *buf, u64 time) |
| 246 { | 304 { |
| 247 event_s *event = buf; | 305 event_s *event = buf; |
| 248 | 306 |
| 249 if (Trace_self) { | 307 if (Trace_self) { |
| 250 if (!do_ignore_pid(event->pid)) { | 308 if (!do_ignore_pid(event->pid)) { |
| 251 return; | 309 return; |
| 252 } | 310 } |
| 253 ++MyPidCount; | 311 ++MyPidCount; |
| 254 } else { | 312 } else { |
| 255 if (do_ignore_pid(event->pid)) { | 313 if (do_ignore_pid(event->pid)) { |
| 256 ++MyPidCount; | 314 ++MyPidCount; |
| 257 return; | 315 return; |
| 258 } | 316 } |
| 259 } | 317 } |
| 260 switch (event->type) { | 318 switch (event->type) { |
| 261 case 21: | 319 case 21: |
| 262 » » process_sys_exit(event); | 320 » » parse_sys_exit(event, time); |
| 263 break; | 321 break; |
| 264 case 22: | 322 case 22: |
| 265 » » process_sys_enter(event); | 323 » » parse_sys_enter(event, time); |
| 266 break; | 324 break; |
| 267 default: | 325 default: |
| 268 //printf(" no processing\n"); | 326 //printf(" no processing\n"); |
| 269 break; | 327 break; |
| 270 } | 328 } |
| 271 } | 329 } |
| 272 | 330 |
| 273 static unint process_buf(u8 *buf) | 331 static unint parse_buf(u8 *buf) |
| 274 { | 332 { |
| 275 ring_header_s *rh = (ring_header_s *)buf; | 333 ring_header_s *rh = (ring_header_s *)buf; |
| 276 ring_event_s *r; | 334 ring_event_s *r; |
| 277 unint commit; | 335 unint commit; |
| 278 unint length; | 336 unint length; |
| 279 unint size; | 337 unint size; |
| 280 u64 time; | 338 u64 time; |
| 281 u8 *end; | 339 u8 *end; |
| 282 | 340 |
| 283 time = rh->time_stamp; | 341 time = rh->time_stamp; |
| 284 commit = rh->commit; | 342 commit = rh->commit; |
| 285 buf += sizeof(*rh); | 343 buf += sizeof(*rh); |
| 286 end = &buf[commit]; | 344 end = &buf[commit]; |
| 287 pthread_mutex_lock(&Count_lock); | 345 pthread_mutex_lock(&Count_lock); |
| 288 for (; buf < end; buf += size) { | 346 for (; buf < end; buf += size) { |
| 289 r = (ring_event_s *)buf; | 347 r = (ring_event_s *)buf; |
| 290 if (r->type_len == 0) { | 348 if (r->type_len == 0) { |
| 291 /* Larger record where size is at beginning of record */ | 349 /* Larger record where size is at beginning of record */ |
| 292 length = r->array[0]; | 350 length = r->array[0]; |
| 293 size = 4 + length * 4; | 351 size = 4 + length * 4; |
| 294 time += r->time_delta; | 352 time += r->time_delta; |
| 295 } else if (r->type_len <= 28) { | 353 } else if (r->type_len <= 28) { |
| 296 /* Data record */ | 354 /* Data record */ |
| 297 length = r->type_len; | 355 length = r->type_len; |
| 298 size = 4 + length * 4; | 356 size = 4 + length * 4; |
| 299 time += r->time_delta; | 357 time += r->time_delta; |
| 300 » » » process_event(buf+4); | 358 » » » parse_event(buf+4, time); |
| 301 } else if (r->type_len == 29) { | 359 } else if (r->type_len == 29) { |
| 302 /* Left over page padding or discarded event */ | 360 /* Left over page padding or discarded event */ |
| 303 if (r->time_delta == 0) { | 361 if (r->time_delta == 0) { |
| 304 goto done; | 362 goto done; |
| 305 } else { | 363 } else { |
| 306 length = r->array[0]; | 364 length = r->array[0]; |
| 307 size = 4 + length * 4; | 365 size = 4 + length * 4; |
| 308 } | 366 } |
| 309 } else if (r->type_len == 30) { | 367 } else if (r->type_len == 30) { |
| 310 /* Extended time delta */ | 368 /* Extended time delta */ |
| 311 size = 8; | 369 size = 8; |
| 312 time += (((u64)r->array[0]) << 28) | r->time_delta; | 370 time += (((u64)r->array[0]) << 28) | r->time_delta; |
| 313 } else if (r->type_len == 31) { | 371 } else if (r->type_len == 31) { |
| 314 /* Sync time with external clock (NOT IMMPLEMENTED) */ | 372 /* Sync time with external clock (NOT IMMPLEMENTED) */ |
| 315 » » » //tv_nsec = r->array[0]; | 373 » » » time = r->array[0]; |
| 316 » » » //tv_sec = *(u64 *)&(r->array[1]); | 374 » » » time += *(u64 *)&(r->array[1]) * A_BILLION; |
| 317 } else { | 375 } else { |
| 318 warn(" Unknown event %d", r->type_len); | 376 warn(" Unknown event %d", r->type_len); |
| 319 /* Unknown - ignore */ | 377 /* Unknown - ignore */ |
| 320 size = 4; | 378 size = 4; |
| 321 } | 379 } |
| 322 } | 380 } |
| 323 done: | 381 done: |
| 324 pthread_mutex_unlock(&Count_lock); | 382 pthread_mutex_unlock(&Count_lock); |
| 325 return commit; | 383 return commit; |
| 326 } | 384 } |
| 327 | 385 |
| 328 void pr_buf(int cpu, int sz, u8 buf[sz]) | |
| 329 { | |
| 330 int i; | |
| 331 int j; | |
| 332 | |
| 333 printf("%d. trace=%d bytes\n", cpu, sz); | |
| 334 for (i = 0; i < sz; i++) { | |
| 335 for (j = 0; j < 32; j++, i++) { | |
| 336 if (i == sz) goto done; | |
| 337 printf(" %2x", buf[i]); | |
| 338 } | |
| 339 printf("\n"); | |
| 340 } | |
| 341 done: | |
| 342 printf("\n"); | |
| 343 } | |
| 344 | |
| 345 static void pr_event(event_s *event) | |
| 346 { | |
| 347 printf(" type=%2u flags=%2x cnt=%2d pid=%5d lock=%2d", | |
| 348 event->type, event->flags, event->preempt_count, event->pid, | |
| 349 event->lock_depth); | |
| 350 } | |
| 351 | |
| 352 static void pr_sys_enter(void *event) | |
| 353 { | |
| 354 sys_enter_s *sy = event; | |
| 355 int i; | |
| 356 | |
| 357 printf(" %-20s", Syscall[sy->id]); | |
| 358 for (i = 0; i < 6; i++) { | |
| 359 printf(" %ld", sy->args[i]); | |
| 360 } | |
| 361 printf("\n"); | |
| 362 } | |
| 363 | |
| 364 static void pr_sys_exit(void *event) | |
| 365 { | |
| 366 sys_exit_s *sy = event; | |
| 367 | |
| 368 printf(" %-20s ret=%ld\n", Syscall[sy->id], sy->ret); | |
| 369 } | |
| 370 | |
| 371 static void pr_ring_header(ring_header_s *rh) | |
| 372 { | |
| 373 printf("%lld %lld %ld\n", | |
| 374 rh->time_stamp / A_BILLION, rh->time_stamp % A_BILLION, | |
| 375 rh->commit); | |
| 376 } | |
| 377 | |
| 378 static void dump_event(void *buf) | |
| 379 { | |
| 380 event_s *event = buf; | |
| 381 | |
| 382 pr_event(event); | |
| 383 switch (event->type) { | |
| 384 case 21: | |
| 385 pr_sys_exit(event); | |
| 386 break; | |
| 387 case 22: | |
| 388 pr_sys_enter(event); | |
| 389 break; | |
| 390 default: | |
| 391 printf(" no processing\n"); | |
| 392 break; | |
| 393 } | |
| 394 } | |
| 395 | |
| 396 static void dump_buf(u8 *buf) | |
| 397 { | |
| 398 ring_header_s *rh = (ring_header_s *)buf; | |
| 399 ring_event_s *r; | |
| 400 unint length; | |
| 401 unint size; | |
| 402 u64 time; | |
| 403 u8 *end; | |
| 404 | |
| 405 pr_ring_header(rh); | |
| 406 time = rh->time_stamp; | |
| 407 buf += sizeof(*rh); | |
| 408 end = &buf[rh->commit]; | |
| 409 for (; buf < end; buf += size) { | |
| 410 r = (ring_event_s *)buf; | |
| 411 printf("type_len=%2u time=%9d", r->type_len, r->time_delta); | |
| 412 if (r->type_len == 0) { | |
| 413 length = r->array[0]; | |
| 414 size = 4 + length * 4; | |
| 415 time += r->time_delta; | |
| 416 } else if (r->type_len <= 28) { | |
| 417 length = r->type_len; | |
| 418 size = 4 + length * 4; | |
| 419 time += r->time_delta; | |
| 420 dump_event(buf+4); | |
| 421 } else if (r->type_len == 29) { | |
| 422 printf("\n"); | |
| 423 if (r->time_delta == 0) { | |
| 424 return; | |
| 425 } else { | |
| 426 length = r->array[0]; | |
| 427 size = 4 + length * 4; | |
| 428 } | |
| 429 } else if (r->type_len == 30) { | |
| 430 /* Extended time delta */ | |
| 431 printf("\n"); | |
| 432 size = 8; | |
| 433 time += (((u64)r->array[0]) << 28) | r->time_delta; | |
| 434 } else if (r->type_len == 31) { | |
| 435 /* Sync time with external clock (NOT IMMPLEMENTED) */ | |
| 436 //tv_nsec = r->array[0]; | |
| 437 //tv_sec = *(u64 *)&(r->array[1]); | |
| 438 } else { | |
| 439 printf(" Unknown event %d\n", r->type_len); | |
| 440 /* Unknown - ignore */ | |
| 441 size = 4; | |
| 442 } | |
| 443 } | |
| 444 } | |
| 445 | |
| 446 static void dump_raw(int cpu, int sz, u8 buf[sz]) | |
| 447 { | |
| 448 dump_buf(buf); // Need to do something with sz | |
| 449 } | |
| 450 | |
| 451 void *collector(void *args) | 386 void *collector(void *args) |
| 452 { | 387 { |
| 453 Collector_args_s *a = args; | 388 Collector_args_s *a = args; |
| 454 /* | 389 /* |
| 455 * 1 ms -> 7% overhead | 390 * 1 ms -> 7% overhead |
| 456 * 10 ms -> 1% overhead | 391 * 10 ms -> 1% overhead |
| 457 */ | 392 */ |
| 458 struct timespec sleep = { 0, 10 * A_MILLION }; | 393 struct timespec sleep = { 0, 10 * A_MILLION }; |
| 459 u8 buf[BUF_SIZE]; | 394 u8 buf[BUF_SIZE]; |
| 460 int cpu = a->cpu_id; | 395 int cpu = a->cpu_id; |
| 461 int trace_pipe; | 396 int trace_pipe; |
| 462 int rc; | 397 int rc; |
| 463 int i; | 398 int i; |
| 464 | 399 |
| 465 ignore_pid(gettid()); | 400 ignore_pid(gettid()); |
| 466 » trace_pipe = init_raw(cpu); | 401 » trace_pipe = open_raw(cpu); |
| 467 for (i = 0;; i++) { | 402 for (i = 0;; i++) { |
| 468 rc = read(trace_pipe, buf, sizeof(buf)); | 403 rc = read(trace_pipe, buf, sizeof(buf)); |
| 469 if (rc == -1) { | 404 if (rc == -1) { |
| 470 close(trace_pipe); | 405 close(trace_pipe); |
| 471 cleanup(0); | 406 cleanup(0); |
| 472 } | 407 } |
| 473 » » rc = process_buf(buf); | 408 » » rc = parse_buf(buf); |
| 474 if (rc < SMALL_READ) { | 409 if (rc < SMALL_READ) { |
| 475 ++Slept; | 410 ++Slept; |
| 476 nanosleep(&sleep, NULL); | 411 nanosleep(&sleep, NULL); |
| 477 // sleep(1); // Wait for input to accumulate | |
| 478 } | 412 } |
| 479 } | 413 } |
| 480 return NULL; | 414 return NULL; |
| 481 } | |
| 482 | |
| 483 static void *dump_collector(void *args) | |
| 484 { | |
| 485 Collector_args_s *a = args; | |
| 486 u8 buf[BUF_SIZE]; | |
| 487 int cpu = a->cpu_id; | |
| 488 int trace_pipe; | |
| 489 int rc; | |
| 490 int i; | |
| 491 | |
| 492 ignore_pid(gettid()); | |
| 493 trace_pipe = init_raw(cpu); | |
| 494 for (i = 0;; i++) { | |
| 495 rc = read(trace_pipe, buf, sizeof(buf)); | |
| 496 printf("i=%d rc=%d\n", i, rc); | |
| 497 if (rc == -1) { | |
| 498 close(trace_pipe); | |
| 499 cleanup(0); | |
| 500 } | |
| 501 dump_raw(cpu, rc, buf); | |
| 502 if (rc < SMALL_READ) { | |
| 503 ++Slept; | |
| 504 sleep(1); // Wait for input to accumulate | |
| 505 } | |
| 506 } | |
| 507 return NULL; | |
| 508 } | 415 } |
| 509 | 416 |
| 510 void cleanup_collector(void) | 417 void cleanup_collector(void) |
| 511 { | 418 { |
| 512 disable_sys_enter(); | 419 disable_sys_enter(); |
| 513 disable_sys_exit(); | 420 disable_sys_exit(); |
| 514 } | 421 } |
| 515 | 422 |
| 516 void start_collector(void) | 423 void start_collector(void) |
| 517 { | 424 { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 528 num_cpus = sysconf(_SC_NPROCESSORS_CONF); | 435 num_cpus = sysconf(_SC_NPROCESSORS_CONF); |
| 529 if (Dump) num_cpus = 1; // for now while playing with it | 436 if (Dump) num_cpus = 1; // for now while playing with it |
| 530 args = ezalloc(num_cpus * sizeof(Collector_args_s)); | 437 args = ezalloc(num_cpus * sizeof(Collector_args_s)); |
| 531 for (i = 0; i < num_cpus; i++, args++) { | 438 for (i = 0; i < num_cpus; i++, args++) { |
| 532 args->cpu_id = i; | 439 args->cpu_id = i; |
| 533 rc = pthread_create(&collector_thread, NULL, | 440 rc = pthread_create(&collector_thread, NULL, |
| 534 Dump ? dump_collector : collector, args); | 441 Dump ? dump_collector : collector, args); |
| 535 if (rc) fatal("Couldn't create collector %d:", rc); | 442 if (rc) fatal("Couldn't create collector %d:", rc); |
| 536 } | 443 } |
| 537 } | 444 } |
| OLD | NEW |