Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(159)

Unified Diff: collector.c

Issue 6893111: Enhancements to ktop (Closed) Base URL: ssh://gitrw.chromium.org:9222/ktop.git@master
Patch Set: Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « collector.h ('k') | debug.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: collector.c
diff --git a/collector.c b/collector.c
index 46ffd5a90d80aece4402630e0d18de3d32f1d14d..cb58005122a100006a90308febac5cf08404e806 100644
--- a/collector.c
+++ b/collector.c
@@ -13,51 +13,20 @@
#include <sys/stat.h>
#include <fcntl.h>
+#include <debug.h>
#include <eprintf.h>
+#include <mylib.h>
#include <style.h>
-#include "syscall.h"
+#include "collector.h"
#include "ktop.h"
+#include "syscall.h"
#define _STR(x) #x
#define STR(x) _STR(x)
#define MAX_PATH 256
-enum { BUF_SIZE = 1 << 12,
- SMALL_READ = BUF_SIZE >> 2 };
-
-typedef struct ring_header_s {
- u64 time_stamp;
- unint commit;
- u8 data[];
-} ring_header_s;
-
-typedef struct ring_event_s {
- u32 type_len : 5,
- time_delta : 27;
- u32 array[];
-} ring_event_s;
-
-typedef struct event_s {
- u16 type;
- u8 flags;
- u8 preempt_count;
- s32 pid;
- s32 lock_depth;
-} event_s;
-
-typedef struct sys_enter_s {
- event_s ev;
- snint id;
- unint args[6];
-} sys_enter_s;
-
-typedef struct sys_exit_s {
- event_s ev;
- snint id;
- snint ret;
-} sys_exit_s;
-
+enum { PIDCALL_BUCKETS = 1543 };
pthread_mutex_t Count_lock = PTHREAD_MUTEX_INITIALIZER;
@@ -66,6 +35,19 @@ u64 MyPidCount;
u64 Slept;
int Pid[MAX_PID];
+Pidcall_s Pidcall[MAX_PIDCALLS];
+Pidcall_s *Pidclock = Pidcall;
+u64 PidcallIterations;
+u64 PidcallRecord;
+u64 Pidcall_tick;
+
+u64 No_enter;
+u64 Found;
+u64 Out_of_order;
+u64 No_start;
+
+Pidcall_s *Pidcall_bucket[PIDCALL_BUCKETS];
+
static const char *find_debugfs(void)
{
static char debugfs[MAX_PATH+1];
@@ -169,7 +151,7 @@ static void disable_sys_exit (void)
disable_event("sys_exit");
}
-static int init_raw(int cpu)
+int open_raw(int cpu)
{
char name[MAX_NAME];
int fd;
@@ -182,50 +164,98 @@ static int init_raw(int cpu)
return fd;
}
-Pidcall_s Pidcall[MAX_PIDCALLS];
-Pidcall_s *Pidnext = Pidcall;
+static Pidcall_s *hash_pidcall(u32 pidcall)
+{
+ return (Pidcall_s *)&Pidcall_bucket[pidcall % PIDCALL_BUCKETS];
+}
-static inline void swap_pidcall(Pidcall_s *p)
+static Pidcall_s *find_pidcall(u32 pidcall)
{
- Pidcall_s tmp;
+ Pidcall_s *pc = hash_pidcall(pidcall);
+
+++PidcallRecord;
+ for (;;) {
+++PidcallIterations;
+ pc = pc->next;
+ if (!pc) return NULL;
+ if (pc->pidcall == pidcall) {
+ pc->clock = 1;
+ return pc;
+ }
+ }
+}
- if (p == Pidcall) return;
- tmp = *p;
- *p = p[-1];
- p[-1] = tmp;
+#if 0
+static void dump(char *label, Pidcall_s *pc)
+{
+ int i;
+
+ fprintf(stderr, "%s", label);
+ for (i = 0; (i < 10) && pc; i++) {
+ fprintf(stderr, " %p", pc);
+ pc = pc->next;
+ }
+ if (pc) fprintf(stderr, "STUCK");
+ fprintf(stderr, "\n");
}
+#endif
-void record_pid_syscall (u32 pidcall)
+static void add_pidcall(Pidcall_s *pidcall)
{
- Pidcall_s *p;
+ Pidcall_s *pc = hash_pidcall(pidcall->pidcall);
+
+ pidcall->next = pc->next;
+ pc->next = pidcall;
+}
- for (p = Pidcall; p < Pidnext; p++) {
- if (p->pidcall == pidcall) {
- ++p->count;
- swap_pidcall(p);
+static void rmv_pidcall(u32 pidcall)
+{
+ Pidcall_s *prev = hash_pidcall(pidcall);
+ Pidcall_s *next;
+
+ for (;;) {
+ next = prev->next;
+ if (!next) return;
+ if (next->pidcall == pidcall) {
+ prev->next = next->next;
return;
}
+ prev = next;
}
- if (Pidnext == &Pidcall[MAX_PIDCALLS]) {
- /*
- * Need a better method but this might be good enough
- */
- --p;
- p->pidcall = pidcall;
- p->count = 1;
- swap_pidcall(p);
- return;
+}
+
+static Pidcall_s *victim_pidcall(u32 pidcall)
+{
+ Pidcall_s *pc = Pidclock;
+
+ while (pc->clock) {
+++Pidcall_tick;
+ pc->clock = 0;
+ if (++Pidclock == &Pidcall[MAX_PIDCALLS]) {
+ Pidclock = Pidcall;
+ }
+ pc = Pidclock;
+ }
+ if (pc->pidcall) {
+ rmv_pidcall(pc->pidcall);
}
- p = Pidnext++;
- p->pidcall = pidcall;
- p->count = 1;
+ if (pc->name) {
+ free(pc->name);
+ }
+ zero(*pc);
+ pc->pidcall = pidcall;
+ add_pidcall(pc);
+
+ return pc;
}
-static void process_sys_enter(void *event)
+static void parse_sys_enter(void *event, u64 time)
{
sys_enter_s *sy = event;
- int pid = sy->ev.pid;
- snint call_num = sy->id;
+ int pid = sy->ev.pid;
+ snint call_num = sy->id;
+ u32 pidcall = mkpidcall(pid, call_num);
+ Pidcall_s *pc;
++Pid[pid];
@@ -234,15 +264,43 @@ static void process_sys_enter(void *event)
return;
}
++Syscall_count[call_num];
- record_pid_syscall(mkpidcall(pid, call_num));
+
+ pc = find_pidcall(pidcall);
+ if (!pc) {
+ pc = victim_pidcall(pidcall);
+ }
+ ++pc->count;
+ pc->time.start = time;
+ memmove(pc->arg, sy->arg, sizeof(pc->arg));
}
-static void process_sys_exit(void *event)
+static void parse_sys_exit(void *event, u64 time)
{
-// sys_exit_s *sy = event;
+ sys_exit_s *sy = event;
+ int pid = sy->ev.pid;
+ snint call_num = sy->id;
+ u32 pidcall = mkpidcall(pid, call_num);
+ Pidcall_s *pc;
+
+ pc = find_pidcall(pidcall);
+ if (!pc) {
+ ++No_enter;
+ return;
+ }
+ if (pc->time.start) {
+ if (time > pc->time.start) {
+ ++Found;
+ pc->time.total += time - pc->time.start;
+ } else {
+ ++Out_of_order;
+ }
+ pc->time.start = 0;
+ } else {
+ ++No_start;
+ }
}
-static void process_event(void *buf)
+static void parse_event(void *buf, u64 time)
{
event_s *event = buf;
@@ -259,10 +317,10 @@ static void process_event(void *buf)
}
switch (event->type) {
case 21:
- process_sys_exit(event);
+ parse_sys_exit(event, time);
break;
case 22:
- process_sys_enter(event);
+ parse_sys_enter(event, time);
break;
default:
//printf(" no processing\n");
@@ -270,7 +328,7 @@ static void process_event(void *buf)
}
}
-static unint process_buf(u8 *buf)
+static unint parse_buf(u8 *buf)
{
ring_header_s *rh = (ring_header_s *)buf;
ring_event_s *r;
@@ -297,7 +355,7 @@ static unint process_buf(u8 *buf)
length = r->type_len;
size = 4 + length * 4;
time += r->time_delta;
- process_event(buf+4);
+ parse_event(buf+4, time);
} else if (r->type_len == 29) {
/* Left over page padding or discarded event */
if (r->time_delta == 0) {
@@ -312,8 +370,8 @@ static unint process_buf(u8 *buf)
time += (((u64)r->array[0]) << 28) | r->time_delta;
} else if (r->type_len == 31) {
/* Sync time with external clock (NOT IMMPLEMENTED) */
- //tv_nsec = r->array[0];
- //tv_sec = *(u64 *)&(r->array[1]);
+ time = r->array[0];
+ time += *(u64 *)&(r->array[1]) * A_BILLION;
} else {
warn(" Unknown event %d", r->type_len);
/* Unknown - ignore */
@@ -325,129 +383,6 @@ done:
return commit;
}
-void pr_buf(int cpu, int sz, u8 buf[sz])
-{
- int i;
- int j;
-
- printf("%d. trace=%d bytes\n", cpu, sz);
- for (i = 0; i < sz; i++) {
- for (j = 0; j < 32; j++, i++) {
- if (i == sz) goto done;
- printf(" %2x", buf[i]);
- }
- printf("\n");
- }
-done:
- printf("\n");
-}
-
-static void pr_event(event_s *event)
-{
- printf(" type=%2u flags=%2x cnt=%2d pid=%5d lock=%2d",
- event->type, event->flags, event->preempt_count, event->pid,
- event->lock_depth);
-}
-
-static void pr_sys_enter(void *event)
-{
- sys_enter_s *sy = event;
- int i;
-
- printf(" %-20s", Syscall[sy->id]);
- for (i = 0; i < 6; i++) {
- printf(" %ld", sy->args[i]);
- }
- printf("\n");
-}
-
-static void pr_sys_exit(void *event)
-{
- sys_exit_s *sy = event;
-
- printf(" %-20s ret=%ld\n", Syscall[sy->id], sy->ret);
-}
-
-static void pr_ring_header(ring_header_s *rh)
-{
- printf("%lld %lld %ld\n",
- rh->time_stamp / A_BILLION, rh->time_stamp % A_BILLION,
- rh->commit);
-}
-
-static void dump_event(void *buf)
-{
- event_s *event = buf;
-
- pr_event(event);
- switch (event->type) {
- case 21:
- pr_sys_exit(event);
- break;
- case 22:
- pr_sys_enter(event);
- break;
- default:
- printf(" no processing\n");
- break;
- }
-}
-
-static void dump_buf(u8 *buf)
-{
- ring_header_s *rh = (ring_header_s *)buf;
- ring_event_s *r;
- unint length;
- unint size;
- u64 time;
- u8 *end;
-
- pr_ring_header(rh);
- time = rh->time_stamp;
- buf += sizeof(*rh);
- end = &buf[rh->commit];
- for (; buf < end; buf += size) {
- r = (ring_event_s *)buf;
- printf("type_len=%2u time=%9d", r->type_len, r->time_delta);
- if (r->type_len == 0) {
- length = r->array[0];
- size = 4 + length * 4;
- time += r->time_delta;
- } else if (r->type_len <= 28) {
- length = r->type_len;
- size = 4 + length * 4;
- time += r->time_delta;
- dump_event(buf+4);
- } else if (r->type_len == 29) {
- printf("\n");
- if (r->time_delta == 0) {
- return;
- } else {
- length = r->array[0];
- size = 4 + length * 4;
- }
- } else if (r->type_len == 30) {
- /* Extended time delta */
- printf("\n");
- size = 8;
- time += (((u64)r->array[0]) << 28) | r->time_delta;
- } else if (r->type_len == 31) {
- /* Sync time with external clock (NOT IMMPLEMENTED) */
- //tv_nsec = r->array[0];
- //tv_sec = *(u64 *)&(r->array[1]);
- } else {
- printf(" Unknown event %d\n", r->type_len);
- /* Unknown - ignore */
- size = 4;
- }
- }
-}
-
-static void dump_raw(int cpu, int sz, u8 buf[sz])
-{
- dump_buf(buf); // Need to do something with sz
-}
-
void *collector(void *args)
{
Collector_args_s *a = args;
@@ -463,45 +398,17 @@ void *collector(void *args)
int i;
ignore_pid(gettid());
- trace_pipe = init_raw(cpu);
+ trace_pipe = open_raw(cpu);
for (i = 0;; i++) {
rc = read(trace_pipe, buf, sizeof(buf));
if (rc == -1) {
close(trace_pipe);
cleanup(0);
}
- rc = process_buf(buf);
+ rc = parse_buf(buf);
if (rc < SMALL_READ) {
++Slept;
nanosleep(&sleep, NULL);
- // sleep(1); // Wait for input to accumulate
- }
- }
- return NULL;
-}
-
-static void *dump_collector(void *args)
-{
- Collector_args_s *a = args;
- u8 buf[BUF_SIZE];
- int cpu = a->cpu_id;
- int trace_pipe;
- int rc;
- int i;
-
- ignore_pid(gettid());
- trace_pipe = init_raw(cpu);
- for (i = 0;; i++) {
- rc = read(trace_pipe, buf, sizeof(buf));
- printf("i=%d rc=%d\n", i, rc);
- if (rc == -1) {
- close(trace_pipe);
- cleanup(0);
- }
- dump_raw(cpu, rc, buf);
- if (rc < SMALL_READ) {
- ++Slept;
- sleep(1); // Wait for input to accumulate
}
}
return NULL;
« no previous file with comments | « collector.h ('k') | debug.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698