OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
| 3 * Distributed under the terms of the GNU General Public License v2 |
| 4 */ |
| 5 |
| 6 #include <pthread.h> |
| 7 #include <stdlib.h> |
| 8 #include <string.h> |
| 9 #include <time.h> |
| 10 #include <unistd.h> |
| 11 |
| 12 #include <debug.h> |
| 13 #include <eprintf.h> |
| 14 #include <style.h> |
| 15 |
| 16 #include "ktop.h" |
| 17 #include "reduce.h" |
| 18 #include "syscall.h" |
| 19 #include "tickcounter.h" |
| 20 |
| 21 extern pthread_mutex_t Count_lock; |
| 22 |
| 23 |
| 24 struct timespec Sleep = { 1, 0 }; |
| 25 |
| 26 static u64 A[NUM_SYS_CALLS]; |
| 27 static u64 B[NUM_SYS_CALLS]; |
| 28 |
| 29 u64 *Old = A; |
| 30 u64 *New = B; |
| 31 int Delta[NUM_SYS_CALLS]; |
| 32 void *Rank_pidcall[MAX_PIDCALLS]; |
| 33 int Num_rank; |
| 34 |
| 35 TickCounter_s TotalDelta; |
| 36 |
| 37 static int compare_pidcall(const void *a, const void *b) |
| 38 { |
| 39 const Pidcall_s *p = *(const Pidcall_s **)a; |
| 40 const Pidcall_s *q = *(const Pidcall_s **)b; |
| 41 |
| 42 if (p->save.count > q->save.count) return -1; |
| 43 if (p->save.count == q->save.count) return 0; |
| 44 return 1; |
| 45 } |
| 46 |
| 47 static void reduce_pidcall(void) |
| 48 { |
| 49 Pidcall_s *pc; |
| 50 int j; |
| 51 |
| 52 pthread_mutex_lock(&Count_lock); |
| 53 for (pc = Pidcall, j = 0; pc < &Pidcall[MAX_PIDCALLS]; pc++) { |
| 54 if (pc->count) { |
| 55 Rank_pidcall[j++] = pc; |
| 56 pc->save.count = pc->count; |
| 57 pc->count = 0; |
| 58 pc->save.time = pc->time.total; |
| 59 pc->time.total = 0; |
| 60 } |
| 61 } |
| 62 pthread_mutex_unlock(&Count_lock); |
| 63 Num_rank = j; |
| 64 if (1) { |
| 65 qsort(Rank_pidcall, j, sizeof(void *), compare_pidcall); |
| 66 } |
| 67 } |
| 68 |
| 69 static void delta(void) |
| 70 { |
| 71 u64 *tmp; |
| 72 int sum; |
| 73 int i; |
| 74 |
| 75 tmp = Old; |
| 76 Old = New; |
| 77 New = tmp; |
| 78 |
| 79 if (0) { |
| 80 pthread_mutex_lock(&Count_lock); |
| 81 memmove(New, Syscall_count, sizeof(Syscall_count)); |
| 82 memset(Syscall_count, 0, sizeof(Syscall_count)); |
| 83 pthread_mutex_unlock(&Count_lock); |
| 84 } else { |
| 85 memmove(New, Syscall_count, sizeof(Syscall_count)); |
| 86 } |
| 87 |
| 88 sum = 0; |
| 89 for (i = 0; i < NUM_SYS_CALLS; i++) { |
| 90 if (0) { |
| 91 Delta[i] = New[i]; |
| 92 } else { |
| 93 Delta[i] = New[i] - Old[i]; |
| 94 sum += Delta[i]; |
| 95 } |
| 96 } |
| 97 tick(&TotalDelta, sum); |
| 98 } |
| 99 |
| 100 void decrease_reduce_interval(void) |
| 101 { |
| 102 if (Sleep.tv_sec == 1) { |
| 103 Sleep.tv_sec = 0; |
| 104 Sleep.tv_nsec = 500 * A_MILLION; |
| 105 } else if (Sleep. tv_sec > 1) { |
| 106 Sleep.tv_sec >>= 1; |
| 107 } else if (Sleep.tv_nsec > A_MILLION) { |
| 108 Sleep.tv_nsec >>= 1; |
| 109 } |
| 110 } |
| 111 |
| 112 void increase_reduce_interval(void) |
| 113 { |
| 114 if (Sleep.tv_nsec >= 500 * A_MILLION) { |
| 115 Sleep.tv_sec = 1; |
| 116 Sleep.tv_nsec = 0; |
| 117 } else if (Sleep. tv_sec >= 1) { |
| 118 Sleep.tv_sec <<= 1; |
| 119 } else { |
| 120 Sleep.tv_nsec <<= 1; |
| 121 } |
| 122 } |
| 123 |
| 124 void reset_reduce(void) |
| 125 { |
| 126 zero(A); |
| 127 zero(B); |
| 128 zero(Pid); |
| 129 zero(Syscall_count); |
| 130 MyPidCount = 0; |
| 131 Slept = 0; |
| 132 } |
| 133 |
| 134 void *reduce(void *arg) |
| 135 { |
| 136 ignore_pid(gettid()); |
| 137 init_display(); |
| 138 |
| 139 for (;;) { |
| 140 if (Halt) return NULL; |
| 141 delta(); |
| 142 reduce_pidcall(); |
| 143 Display(); |
| 144 nanosleep(&Sleep, NULL); |
| 145 } |
| 146 } |
OLD | NEW |