| Index: display.c | 
| diff --git a/display.c b/display.c | 
| index 35880cd1197a5ff92d05462f19a9c3884d6eb3f4..bddc530e017a28a974e473f16dffa381a885be88 100644 | 
| --- a/display.c | 
| +++ b/display.c | 
| @@ -7,81 +7,107 @@ | 
| #include <stdio.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 "plot.h" | 
| +#include "reduce.h" | 
| #include "syscall.h" | 
| #include "tickcounter.h" | 
|  | 
| enum {	HELP_ROW = 0, | 
| HELP_COL = 0, | 
| +	TOP_ROW  = HELP_ROW + 1, | 
| +	TOP_COL  = 0, | 
| RW_ROW   = HELP_ROW + 1, | 
| RW_COL   = 0, | 
| -	PID_ROW  = RW_ROW + 6, | 
| +	PID_ROW  = TOP_ROW + 12, | 
| PID_COL  = 0, | 
| -	TOP_ROW  = RW_ROW + 6, | 
| -	TOP_COL  = 70, | 
| SELF_ROW = HELP_ROW + 1, | 
| -	SELF_COL = 40 }; | 
| +	SELF_COL = 0, | 
| +	MAX_ROW  = SELF_ROW, | 
| +	MAX_COL  = SELF_COL + 40, | 
| +}; | 
|  | 
| typedef struct Top_ten_s { | 
| int	syscall; | 
| int	value; | 
| } Top_ten_s; | 
|  | 
| +typedef struct Display_call_s { | 
| +	char	*name; | 
| +	int	index; | 
| +} Display_call_s; | 
| + | 
| bool Plot = FALSE; | 
|  | 
| -static u64 A[NUM_SYS_CALLS]; | 
| -static u64 B[NUM_SYS_CALLS]; | 
| -static u64 *Old = A; | 
| -static u64 *New = B; | 
| -static int Delta[NUM_SYS_CALLS]; | 
| static Top_ten_s Top_ten[10]; | 
|  | 
| -static TickCounter_s TotalDelta; | 
| static graph_s TotalGraph = {{0, 0}, {{0, 10}, {60, 20}}}; | 
|  | 
| +Display_call_s Display_call[] = { | 
| +	{ "read:  ", sys_read }, | 
| +	{ "write: ", sys_write }, | 
| +	{ "pread: ", sys_pread64 }, | 
| +	{ "pwrite:", sys_pwrite64 }, | 
| +	{ "sync:  ", sys_sync }, | 
| +	{ "fsync: ", sys_fsync }, | 
| +	{ "open:  ", sys_open }, | 
| +	{ "close: ", sys_close }, | 
| +	{ "creat: ", sys_creat }, | 
| +	{ "unlink:", sys_unlink }, | 
| +	{ "stat:  ", sys_stat64 }, | 
| +	{ "fstat: ", sys_fstat64 }, | 
| +	{ "fork:  ", ptregs_fork }, | 
| +	{ "vfork: ", ptregs_vfork }, | 
| +	{ NULL, 0 }}; | 
| + | 
| static void help(void) | 
| { | 
| mvprintw(HELP_ROW, HELP_COL, | 
| -		"q - quit  c - clear"); | 
| +		"q quit  c clear  k kernel ops  i internal ops  f file ops " | 
| +		" < shorter  > longer %d.%.3d", | 
| +		Sleep.tv_sec, Sleep.tv_nsec / A_MILLION); | 
| } | 
|  | 
| -char *getpidname(int pid) | 
| +static void file_system(void) | 
| { | 
| -	char path[100]; | 
| -	static char name[4096]; | 
| -	int rc; | 
| +	Display_call_s *d; | 
| +	int row = RW_ROW; | 
|  | 
| -	snprintf(path, sizeof(path), "/proc/%d/exe", pid); | 
| -	rc = readlink(path, name, sizeof(name)); | 
| -	if (rc == -1) return NULL; | 
| -	name[rc] = '\0'; | 
| - | 
| -	return name; //strdup(name); | 
| -} | 
| +	mvprintw(row,   RW_COL, "            total   hits/sec"); | 
|  | 
| -static void read_write(void) | 
| -{ | 
| -	mvprintw(RW_ROW,   RW_COL, "            total   hits/sec"); | 
| -	mvprintw(RW_ROW+1, RW_COL, "read:  %10lld %10d", | 
| -		New[sys_read], Delta[sys_read]); | 
| -	mvprintw(RW_ROW+2, RW_COL, "write: %10lld %10d", | 
| -		New[sys_write], Delta[sys_write]); | 
| -	mvprintw(RW_ROW+3, RW_COL, "pread: %10lld %10d", | 
| -		New[sys_pread64], Delta[sys_pread64]); | 
| -	mvprintw(RW_ROW+4, RW_COL, "pwrite:%10lld %10d", | 
| -		New[sys_pwrite64], Delta[sys_pwrite64]); | 
| +	for (d = Display_call; d->name; d++) { | 
| +		mvprintw(++row, RW_COL, "%s %10lld %10d", | 
| +			d->name, New[d->index], Delta[d->index]); | 
| +	} | 
| } | 
|  | 
| static void self(void) | 
| { | 
| -	mvprintw(SELF_ROW,   SELF_COL, "Skipped: %8lld", MyPidCount); | 
| -	mvprintw(SELF_ROW+1, SELF_COL, "Slept:   %8lld", Slept); | 
| +	static double max = 0; | 
| +	double avg; | 
| + | 
| +	mvprintw(SELF_ROW,   SELF_COL, "Skipped:     %12lld", MyPidCount); | 
| +	mvprintw(SELF_ROW+1, SELF_COL, "Slept:       %12lld", Slept); | 
| +	mvprintw(SELF_ROW+2, SELF_COL, "Tick:        %12zd", sizeof(TickCounter_s)); | 
| +	mvprintw(SELF_ROW+3, SELF_COL, "No_enter:    %12lld", No_enter); | 
| +	mvprintw(SELF_ROW+4, SELF_COL, "Found:       %12lld", Found); | 
| +	mvprintw(SELF_ROW+5, SELF_COL, "Out_of_order:%12lld", Out_of_order); | 
| +	mvprintw(SELF_ROW+6, SELF_COL, "No_start:    %12lld", No_start); | 
| +	if (1) { | 
| +		mvprintw(SELF_ROW+7, SELF_COL, "Ticks:       %12lld", Pidcall_tick); | 
| +		if (PidcallRecord == 0) return; | 
| +		avg = (double)PidcallIterations / (double)PidcallRecord; | 
| +		PidcallIterations = PidcallRecord = 0; | 
| +		if (avg > max) max =avg; | 
| +		mvprintw(SELF_ROW+8, SELF_COL, "Avg:              %g", avg); | 
| +		mvprintw(SELF_ROW+9, SELF_COL, "Max:              %g", max); | 
| +	} | 
| } | 
|  | 
| static void top_pid(void) | 
| @@ -96,31 +122,59 @@ static void top_pid(void) | 
| pid = i; | 
| } | 
| } | 
| -	mvprintw(TOP_ROW, TOP_COL, "max: %d %d", pid, max); | 
| +	mvprintw(MAX_ROW, MAX_COL, "max: %d %d", pid, max); | 
| +} | 
| + | 
| +static char *getpidname(int pid) | 
| +{ | 
| +	char path[100]; | 
| +	static char name[4096]; | 
| +	int rc; | 
| + | 
| +	snprintf(path, sizeof(path), "/proc/%d/exe", pid); | 
| +	rc = readlink(path, name, sizeof(name)); | 
| +	if (rc == -1) { | 
| +		return NULL; | 
| +	} | 
| +	if (rc == sizeof(name)) { | 
| +		fatal("pid name too long"); | 
| +	} | 
| +	name[rc] = '\0'; | 
| + | 
| +	return strdup(name); | 
| } | 
|  | 
| static void display_pidcall(void) | 
| { | 
| -	Pidcall_s *p = Pidcall; | 
| +	Pidcall_s *pc; | 
| int row = PID_ROW; | 
| int col = PID_COL; | 
| int pid; | 
| int i; | 
|  | 
| -	mvprintw(row++, col, "       pid  total"); | 
| -	for (i = 0; i < 25; i++, p++, row++) { | 
| -		if (p == Pidnext) return; | 
| -		pid = get_pid(p->pidcall); | 
| -		mvprintw(row, col, "%3d. %5d %6d %-22.22s %-28.28s", | 
| -			i+1, pid, p->count, | 
| -			Syscall[get_call(p->pidcall)], | 
| -			getpidname(pid)); | 
| +	mvprintw(row++, col, "%3d    pid  count   duration", Num_rank); | 
| +	for (i = 0; i < 25 && i < Num_rank; i++, row++) { | 
| +		pc = Rank_pidcall[i]; | 
| +		pid = get_pid(pc->pidcall); | 
| +		if (!pc->name) { | 
| +			pc->name = getpidname(pid); | 
| +			if (!pc->name) { | 
| +				pc->name = strdup("(unknown)"); | 
| +			} | 
| +		} | 
| +		mvprintw(row, col, "%3d. %5d %6d %10lld %-22.22s %-28.28s", | 
| +			i + 1, pid, pc->save.count, | 
| +			pc->save.count ? pc->save.time / pc->save.count : 0LL, | 
| +			Syscall[get_call(pc->pidcall)], | 
| +			pc->name); | 
| +		mvprintw(row, col+80, "%8lx %8lx %8lx", | 
| +			pc->arg[0], pc->arg[1], pc->arg[2]); | 
| } | 
| } | 
|  | 
| static void display_top_ten(void) | 
| { | 
| -	int row = TOP_ROW + 1; | 
| +	int row = TOP_ROW; | 
| int i; | 
|  | 
| mvprintw(row++, TOP_COL, "    hits sys_call"); | 
| @@ -160,27 +214,6 @@ static void top_ten(void) | 
| } | 
| } | 
|  | 
| -static void delta(void) | 
| -{ | 
| -	u64 *tmp; | 
| -	int sum; | 
| -	int i; | 
| - | 
| -	tmp = Old; | 
| -	Old = New; | 
| -	New = tmp; | 
| - | 
| -	memmove(New, Syscall_count, sizeof(Syscall_count)); | 
| - | 
| -	sum = 0; | 
| -	for (i = 0; i < NUM_SYS_CALLS; i++) { | 
| -		Delta[i] = New[i] - Old[i]; | 
| -		sum += Delta[i]; | 
| -	} | 
| -	tick(&TotalDelta, sum); | 
| -	top_ten(); | 
| -} | 
| - | 
| static void graph_total(void) | 
| { | 
| vector_s v = new_vector(WHEEL_SIZE); | 
| @@ -198,7 +231,7 @@ static void graph_total(void) | 
| vplot(&TotalGraph, v, '*'); | 
| } | 
|  | 
| -static void init(void) | 
| +void init_display(void) | 
| { | 
| initscr(); | 
| cbreak(); | 
| @@ -210,41 +243,36 @@ static void init(void) | 
| init_counter(&TotalDelta, 1); | 
| } | 
|  | 
| -void *display(void *arg) | 
| +void kernel_display(void) | 
| { | 
| -	struct timespec sleep = { 1, 0 }; | 
| - | 
| -	ignore_pid(gettid()); | 
| -	init(); | 
| -	for (;;) { | 
| -		if (Command) { | 
| -			return NULL; | 
| -		} | 
| -		delta(); | 
| -		if (Plot) { | 
| -			clear(); | 
| -			graph_total(); | 
| -		} else { | 
| -			top_pid(); | 
| -			display_pidcall(); | 
| -			display_top_ten(); | 
| -		} | 
| -		help(); | 
| -		read_write(); | 
| -		self(); | 
| -		refresh(); | 
| -		nanosleep(&sleep, NULL); | 
| +	clear(); | 
| +	top_ten(); | 
| +	if (Plot) { | 
| +		clear(); | 
| +		graph_total(); | 
| +	} else { | 
| +		display_pidcall(); | 
| +		display_top_ten(); | 
| } | 
| +	help(); | 
| +	refresh(); | 
| +} | 
| + | 
| +void internal_display(void) | 
| +{ | 
| +	clear(); | 
| +	help(); | 
| +	self(); | 
| +	top_pid(); | 
| +	refresh(); | 
| } | 
|  | 
| -void clear_display(void) | 
| +void file_system_display(void) | 
| { | 
| -	zero(A); | 
| -	zero(B); | 
| -	zero(Pid); | 
| -	zero(Syscall_count); | 
| -	MyPidCount = 0; | 
| -	Slept = 0; | 
| +	clear(); | 
| +	help(); | 
| +	file_system(); | 
| +	refresh(); | 
| } | 
|  | 
| void cleanup_display(void) | 
|  |