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 |