Index: reduce.c |
diff --git a/reduce.c b/reduce.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..141e73df0ba6ec8465d71dfc84fe13a4f07aa83a |
--- /dev/null |
+++ b/reduce.c |
@@ -0,0 +1,146 @@ |
+/* |
+ * Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
+ * Distributed under the terms of the GNU General Public License v2 |
+ */ |
+ |
+#include <pthread.h> |
+#include <stdlib.h> |
+#include <string.h> |
+#include <time.h> |
+#include <unistd.h> |
+ |
+#include <debug.h> |
+#include <eprintf.h> |
+#include <style.h> |
+ |
+#include "ktop.h" |
+#include "reduce.h" |
+#include "syscall.h" |
+#include "tickcounter.h" |
+ |
+extern pthread_mutex_t Count_lock; |
+ |
+ |
+struct timespec Sleep = { 1, 0 }; |
+ |
+static u64 A[NUM_SYS_CALLS]; |
+static u64 B[NUM_SYS_CALLS]; |
+ |
+u64 *Old = A; |
+u64 *New = B; |
+int Delta[NUM_SYS_CALLS]; |
+void *Rank_pidcall[MAX_PIDCALLS]; |
+int Num_rank; |
+ |
+TickCounter_s TotalDelta; |
+ |
+static int compare_pidcall(const void *a, const void *b) |
+{ |
+ const Pidcall_s *p = *(const Pidcall_s **)a; |
+ const Pidcall_s *q = *(const Pidcall_s **)b; |
+ |
+ if (p->save.count > q->save.count) return -1; |
+ if (p->save.count == q->save.count) return 0; |
+ return 1; |
+} |
+ |
+static void reduce_pidcall(void) |
+{ |
+ Pidcall_s *pc; |
+ int j; |
+ |
+ pthread_mutex_lock(&Count_lock); |
+ for (pc = Pidcall, j = 0; pc < &Pidcall[MAX_PIDCALLS]; pc++) { |
+ if (pc->count) { |
+ Rank_pidcall[j++] = pc; |
+ pc->save.count = pc->count; |
+ pc->count = 0; |
+ pc->save.time = pc->time.total; |
+ pc->time.total = 0; |
+ } |
+ } |
+ pthread_mutex_unlock(&Count_lock); |
+ Num_rank = j; |
+ if (1) { |
+ qsort(Rank_pidcall, j, sizeof(void *), compare_pidcall); |
+ } |
+} |
+ |
+static void delta(void) |
+{ |
+ u64 *tmp; |
+ int sum; |
+ int i; |
+ |
+ tmp = Old; |
+ Old = New; |
+ New = tmp; |
+ |
+ if (0) { |
+ pthread_mutex_lock(&Count_lock); |
+ memmove(New, Syscall_count, sizeof(Syscall_count)); |
+ memset(Syscall_count, 0, sizeof(Syscall_count)); |
+ pthread_mutex_unlock(&Count_lock); |
+ } else { |
+ memmove(New, Syscall_count, sizeof(Syscall_count)); |
+ } |
+ |
+ sum = 0; |
+ for (i = 0; i < NUM_SYS_CALLS; i++) { |
+ if (0) { |
+ Delta[i] = New[i]; |
+ } else { |
+ Delta[i] = New[i] - Old[i]; |
+ sum += Delta[i]; |
+ } |
+ } |
+ tick(&TotalDelta, sum); |
+} |
+ |
+void decrease_reduce_interval(void) |
+{ |
+ if (Sleep.tv_sec == 1) { |
+ Sleep.tv_sec = 0; |
+ Sleep.tv_nsec = 500 * A_MILLION; |
+ } else if (Sleep. tv_sec > 1) { |
+ Sleep.tv_sec >>= 1; |
+ } else if (Sleep.tv_nsec > A_MILLION) { |
+ Sleep.tv_nsec >>= 1; |
+ } |
+} |
+ |
+void increase_reduce_interval(void) |
+{ |
+ if (Sleep.tv_nsec >= 500 * A_MILLION) { |
+ Sleep.tv_sec = 1; |
+ Sleep.tv_nsec = 0; |
+ } else if (Sleep. tv_sec >= 1) { |
+ Sleep.tv_sec <<= 1; |
+ } else { |
+ Sleep.tv_nsec <<= 1; |
+ } |
+} |
+ |
+void reset_reduce(void) |
+{ |
+ zero(A); |
+ zero(B); |
+ zero(Pid); |
+ zero(Syscall_count); |
+ MyPidCount = 0; |
+ Slept = 0; |
+} |
+ |
+void *reduce(void *arg) |
+{ |
+ ignore_pid(gettid()); |
+ init_display(); |
+ |
+ for (;;) { |
+ if (Halt) return NULL; |
+ delta(); |
+ reduce_pidcall(); |
+ Display(); |
+ nanosleep(&Sleep, NULL); |
+ } |
+} |