version 1.19, 2005/04/13 02:33:09 |
version 1.20, 2005/06/08 22:36:43 |
|
|
*/ |
*/ |
|
|
#include <sys/types.h> |
#include <sys/types.h> |
|
#include <sys/time.h> |
|
#include <sys/sched.h> |
#include <stdio.h> |
#include <stdio.h> |
#include <ctype.h> |
#include <ctype.h> |
|
#include <err.h> |
#include <stdlib.h> |
#include <stdlib.h> |
#include <string.h> |
#include <string.h> |
#include <signal.h> |
#include <signal.h> |
|
|
static int lastline = 0; |
static int lastline = 0; |
static int display_width = MAX_COLS; |
static int display_width = MAX_COLS; |
|
|
static char *cpustates_tag(void); |
static char *cpustates_tag(int); |
static int string_count(char **); |
static int string_count(char **); |
static void summary_format(char *, size_t, int *, char **); |
static void summary_format(char *, size_t, int *, char **); |
static void line_update(char *, char *, int, int); |
static void line_update(char *, char *, int, int); |
|
|
static int num_cpustates; |
static int num_cpustates; |
|
|
static int *lprocstates; |
static int *lprocstates; |
static int *lcpustates; |
static int64_t **lcpustates; |
|
|
static int *cpustate_columns; |
static int *cpustate_columns; |
static int cpustate_total_length; |
static int cpustate_total_length; |
|
|
|
/* display ips */ |
|
int y_mem; |
|
int y_message; |
|
int y_header; |
|
int y_idlecursor; |
|
int y_procs; |
|
extern int ncpu; |
|
int Header_lines; |
|
|
static enum { |
static enum { |
OFF, ON, ERASE |
OFF, ON, ERASE |
} header_status = ON; |
} header_status = ON; |
|
|
display_width = MAX_COLS - 1; |
display_width = MAX_COLS - 1; |
|
|
/* now, allocate space for the screen buffer */ |
/* now, allocate space for the screen buffer */ |
screenbuf = (char *) malloc(display_lines * display_width); |
screenbuf = malloc(display_lines * display_width); |
if (screenbuf == (char *) NULL) |
if (screenbuf == NULL) |
return (-1); |
return (-1); |
|
|
/* return number of lines available */ |
/* return number of lines available */ |
|
|
int |
int |
display_init(struct statics * statics) |
display_init(struct statics * statics) |
{ |
{ |
int display_lines, *ip, i; |
int display_lines, *ip, i, cpu; |
char **pp; |
char **pp; |
|
|
|
y_mem = 2 + ncpu; |
|
y_message = 3 + ncpu; |
|
y_header = 4 + ncpu; |
|
y_idlecursor = 3 + ncpu; |
|
y_procs = 5 + ncpu; |
|
Header_lines = 5 + ncpu; |
|
|
/* call resize to do the dirty work */ |
/* call resize to do the dirty work */ |
display_lines = display_resize(); |
display_lines = display_resize(); |
|
|
|
|
/* save pointers and allocate space for names */ |
/* save pointers and allocate space for names */ |
procstate_names = statics->procstate_names; |
procstate_names = statics->procstate_names; |
num_procstates = string_count(procstate_names); |
num_procstates = string_count(procstate_names); |
lprocstates = (int *) malloc(num_procstates * sizeof(int)); |
lprocstates = malloc(num_procstates * sizeof(int)); |
|
if (lprocstates == NULL) |
|
err(1, NULL); |
|
|
cpustate_names = statics->cpustate_names; |
cpustate_names = statics->cpustate_names; |
num_cpustates = string_count(cpustate_names); |
num_cpustates = string_count(cpustate_names); |
lcpustates = (int *) malloc(num_cpustates * sizeof(int)); |
lcpustates = malloc(ncpu * sizeof(int64_t *)); |
cpustate_columns = (int *) malloc(num_cpustates * sizeof(int)); |
if (lcpustates == NULL) |
|
err(1, NULL); |
|
for (cpu = 0; cpu < ncpu; cpu++) { |
|
lcpustates[cpu] = malloc(num_cpustates * sizeof(int64_t)); |
|
if (lcpustates[cpu] == NULL) |
|
err(1, NULL); |
|
} |
|
|
|
cpustate_columns = malloc(num_cpustates * sizeof(int)); |
|
if (cpustate_columns == NULL) |
|
err(1, NULL); |
|
|
memory_names = statics->memory_names; |
memory_names = statics->memory_names; |
|
|
|
|
/* cpustates_tag() calculates the correct tag to use to label the line */ |
/* cpustates_tag() calculates the correct tag to use to label the line */ |
|
|
static char * |
static char * |
cpustates_tag(void) |
cpustates_tag(int cpu) |
{ |
{ |
static char *short_tag = "CPU: "; |
static char *tag; |
static char *long_tag = "CPU states: "; |
static int cpulen, old_width; |
char *use; |
int i; |
|
|
/* |
if (cpulen == 0 && ncpu > 1) { |
* if length + strlen(long_tag) >= screen_width, then we have to use |
/* compute length of the cpu string */ |
* the shorter tag (we subtract 2 to account for ": ") |
for (i = ncpu; i > 0; cpulen++, i /= 10) |
*/ |
continue; |
if (cpustate_total_length + (int) strlen(long_tag) - 2 >= screen_width) |
} |
use = short_tag; |
|
else |
|
use = long_tag; |
|
|
|
/* set cpustates_column accordingly then return result */ |
if (old_width == screen_width) { |
cpustates_column = strlen(use); |
if (ncpu > 1) { |
return (use); |
/* just store the cpu number in the tag */ |
|
i = tag[3 + cpulen]; |
|
snprintf(tag + 3, cpulen + 1, "%.*d", cpulen, cpu); |
|
tag[3 + cpulen] = i; |
|
} |
|
} else { |
|
/* |
|
* use a long tag if it will fit, otherwise use short one. |
|
*/ |
|
free(tag); |
|
if (cpustate_total_length + 10 + cpulen >= screen_width) |
|
i = asprintf(&tag, "CPU%.*d: ", cpulen, cpu); |
|
else |
|
i = asprintf(&tag, "CPU%.*d states: ", cpulen, cpu); |
|
if (i == -1) |
|
tag = NULL; |
|
else { |
|
cpustates_column = strlen(tag); |
|
old_width = screen_width; |
|
} |
|
} |
|
return (tag); |
} |
} |
|
|
void |
void |
i_cpustates(int *states) |
i_cpustates(int64_t *ostates) |
{ |
{ |
int i = 0, value; |
int i, cpu, value; |
|
int64_t *states; |
char **names = cpustate_names, *thisname; |
char **names = cpustate_names, *thisname; |
|
|
/* print tag and bump lastline */ |
for (cpu = 0; cpu < ncpu; cpu++) { |
printf("\n%s", cpustates_tag()); |
/* print tag and bump lastline */ |
lastline++; |
printf("\n%s", cpustates_tag(cpu)); |
|
lastline++; |
|
|
/* now walk thru the names and print the line */ |
/* now walk thru the names and print the line */ |
while ((thisname = *names++) != NULL) { |
names = cpustate_names; |
if (*thisname != '\0') { |
i = 0; |
/* retrieve the value and remember it */ |
states = ostates + (CPUSTATES * cpu); |
value = *states++; |
while ((thisname = *names++) != NULL) { |
|
if (*thisname != '\0') { |
|
/* retrieve the value and remember it */ |
|
value = *states++; |
|
|
/* if percentage is >= 1000, print it as 100% */ |
/* if percentage is >= 1000, print it as 100% */ |
printf((value >= 1000 ? "%s%4.0f%% %s" : "%s%4.1f%% %s"), |
printf((value >= 1000 ? "%s%4.0f%% %s" : |
i++ == 0 ? "" : ", ", |
"%s%4.1f%% %s"), i++ == 0 ? "" : ", ", |
((float) value) / 10., |
((float) value) / 10., thisname); |
thisname); |
} |
} |
} |
} |
|
|
|
/* copy over values into "last" array */ |
/* copy over values into "last" array */ |
memcpy(lcpustates, states, num_cpustates * sizeof(int)); |
memcpy(lcpustates[cpu], ostates, num_cpustates * sizeof(int64_t)); |
|
} |
} |
} |
|
|
void |
void |
u_cpustates(int *states) |
u_cpustates(int64_t *ostates) |
{ |
{ |
char **names = cpustate_names, *thisname; |
char **names, *thisname; |
int value, *lp, *colp; |
int cpu, value, *colp; |
|
int64_t *lp, *states; |
|
|
Move_to(cpustates_column, y_cpustates); |
for (cpu = 0; cpu < ncpu; cpu++) { |
lastline = y_cpustates; |
lastline = y_cpustates + cpu; |
lp = lcpustates; |
states = ostates + (CPUSTATES * cpu); |
colp = cpustate_columns; |
Move_to(cpustates_column, lastline); |
|
lp = lcpustates[cpu]; |
|
colp = cpustate_columns; |
|
|
/* we could be much more optimal about this */ |
/* we could be much more optimal about this */ |
while ((thisname = *names++) != NULL) { |
names = cpustate_names; |
if (*thisname != '\0') { |
while ((thisname = *names++) != NULL) { |
/* did the value change since last time? */ |
if (*thisname != '\0') { |
if (*lp != *states) { |
/* did the value change since last time? */ |
/* yes, move and change */ |
if (*lp != *states) { |
Move_to(cpustates_column + *colp, y_cpustates); |
/* yes, move and change */ |
lastline = y_cpustates; |
lastline = y_cpustates + cpu; |
|
Move_to(cpustates_column + *colp, |
|
lastline); |
|
|
/* retrieve value and remember it */ |
/* retrieve value and remember it */ |
value = *states; |
value = *states; |
|
|
/* if percentage is >= 1000, print it as 100% */ |
/* if percentage is >= 1000, |
printf((value >= 1000 ? "%4.0f" : "%4.1f"), |
* print it as 100% |
((double) value) / 10.); |
*/ |
|
printf((value >= 1000 ? "%4.0f" : |
|
"%4.1f"), ((double) value) / 10.); |
|
|
/* remember it for next time */ |
/* remember it for next time */ |
*lp = *states; |
*lp = *states; |
|
} |
} |
} |
|
/* increment and move on */ |
|
lp++; |
|
states++; |
|
colp++; |
} |
} |
/* increment and move on */ |
|
lp++; |
|
states++; |
|
colp++; |
|
} |
} |
} |
} |
|
|
void |
void |
z_cpustates(void) |
z_cpustates(void) |
{ |
{ |
char **names = cpustate_names, *thisname; |
char **names, *thisname; |
int i = 0, *lp; |
int cpu, i; |
|
int64_t *lp; |
|
|
/* show tag and bump lastline */ |
for (cpu = 0; cpu < ncpu; cpu++) { |
printf("\n%s", cpustates_tag()); |
/* show tag and bump lastline */ |
lastline++; |
printf("\n%s", cpustates_tag(cpu)); |
|
lastline++; |
|
|
while ((thisname = *names++) != NULL) { |
names = cpustate_names; |
if (*thisname != '\0') |
i = 0; |
printf("%s %% %s", i++ == 0 ? "" : ", ", thisname); |
while ((thisname = *names++) != NULL) { |
} |
if (*thisname != '\0') |
|
printf("%s %% %s", i++ == 0 ? "" : ", ", |
|
thisname); |
|
} |
|
|
/* fill the "last" array with all -1s, to insure correct updating */ |
/* fill the "last" array with all -1s, to ensure correct updating */ |
lp = lcpustates; |
lp = lcpustates[cpu]; |
i = num_cpustates; |
i = num_cpustates; |
while (--i >= 0) |
while (--i >= 0) |
*lp++ = -1; |
*lp++ = -1; |
|
} |
} |
} |
|
|
static char memory_buffer[MAX_COLS]; |
static char memory_buffer[MAX_COLS]; |