Bug #204 » top-pcpu.diff
contrib/top/display.c Wed Jun 14 01:45:28 2006 +0000 → contrib/top/display.c Fri Jun 16 18:43:33 2006 +0900 | ||
---|---|---|
static int num_swap;
|
||
static int *lprocstates;
|
||
static int *lcpustates;
|
||
static int *lmemory;
|
||
static int *lswap;
|
||
... | ... | |
num_swap = string_count(swap_names);
|
||
lswap = (int *)malloc(num_swap * sizeof(int));
|
||
num_cpustates = string_count(cpustate_names);
|
||
lcpustates = (int *)malloc(num_cpustates * sizeof(int));
|
||
cpustate_columns = (int *)malloc(num_cpustates * sizeof(int));
|
||
memory_names = statics->memory_names;
|
||
... | ... | |
* Assumptions: cursor is on the PREVIOUS line
|
||
*/
|
||
static int cpustates_column;
|
||
/* cpustates_tag() calculates the correct tag to use to label the line */
|
||
char *cpustates_tag()
|
||
{
|
||
register char *use;
|
||
static char *short_tag = "CPU: ";
|
||
static char *long_tag = "CPU states: ";
|
||
/* if length + strlen(long_tag) >= screen_width, then we have to
|
||
use the shorter tag (we subtract 2 to account for ": ") */
|
||
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 */
|
||
cpustates_column = strlen(use);
|
||
return(use);
|
||
}
|
||
i_cpustates(states)
|
||
register int *states;
|
||
{
|
||
register int i = 0;
|
||
void
|
||
i_cpustates(struct system_info *si)
|
||
{
|
||
register int i;
|
||
register int value;
|
||
register char **names = cpustate_names;
|
||
register char **names;
|
||
register char *thisname;
|
||
int *states = si->cpustates;
|
||
int cpu;
|
||
/* print tag and bump lastline */
|
||
printf("\n%s", cpustates_tag());
|
||
lastline++;
|
||
/* now walk thru the names and print the line */
|
||
while ((thisname = *names++) != NULL)
|
||
{
|
||
if (*thisname != '\0')
|
||
{
|
||
/* retrieve the value and remember it */
|
||
value = *states++;
|
||
/* if percentage is >= 1000, print it as 100% */
|
||
printf((value >= 1000 ? "%s%4.0f%% %s" : "%s%4.1f%% %s"),
|
||
i++ == 0 ? "" : ", ",
|
||
((float)value)/10.,
|
||
thisname);
|
||
}
|
||
}
|
||
/* copy over values into "last" array */
|
||
memcpy(lcpustates, states, num_cpustates * sizeof(int));
|
||
}
|
||
u_cpustates(states)
|
||
register int *states;
|
||
{
|
||
register int value;
|
||
register char **names = cpustate_names;
|
||
for (cpu = 0; cpu < n_cpus; ++cpu) {
|
||
if (n_cpus > 1)
|
||
printf("\nCPU%d states: ", cpu);
|
||
else
|
||
printf("\nCPU states: ");
|
||
lastline++;
|
||
/* now walk thru the names and print the line */
|
||
names = cpustate_names;
|
||
i = 0;
|
||
while ((thisname = *names++) != NULL)
|
||
{
|
||
if (*thisname != '\0')
|
||
{
|
||
/* retrieve the value and remember it */
|
||
value = *states++;
|
||
/* if percentage is >= 1000, print it as 100% */
|
||
printf((value >= 1000 ? "%s%4.0f%% %s" : "%s%4.1f%% %s"),
|
||
i++ == 0 ? "" : ", ",
|
||
((float)value)/10.,
|
||
thisname);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
void
|
||
z_cpustates(struct system_info *si)
|
||
{
|
||
register int i;
|
||
register char **names;
|
||
register char *thisname;
|
||
register int *lp;
|
||
register int *colp;
|
||
Move_to(cpustates_column, y_cpustates);
|
||
lastline = y_cpustates;
|
||
lp = lcpustates;
|
||
colp = cpustate_columns;
|
||
/* we could be much more optimal about this */
|
||
while ((thisname = *names++) != NULL)
|
||
{
|
||
if (*thisname != '\0')
|
||
{
|
||
/* did the value change since last time? */
|
||
if (*lp != *states)
|
||
{
|
||
/* yes, move and change */
|
||
Move_to(cpustates_column + *colp, y_cpustates);
|
||
lastline = y_cpustates;
|
||
/* retrieve value and remember it */
|
||
value = *states;
|
||
/* if percentage is >= 1000, print it as 100% */
|
||
printf((value >= 1000 ? "%4.0f" : "%4.1f"),
|
||
((double)value)/10.);
|
||
/* remember it for next time */
|
||
*lp = value;
|
||
}
|
||
}
|
||
/* increment and move on */
|
||
lp++;
|
||
states++;
|
||
colp++;
|
||
}
|
||
}
|
||
z_cpustates()
|
||
{
|
||
register int i = 0;
|
||
register char **names = cpustate_names;
|
||
register char *thisname;
|
||
register int *lp;
|
||
int cpu;
|
||
/* show tag and bump lastline */
|
||
printf("\n%s", cpustates_tag());
|
||
lastline++;
|
||
while ((thisname = *names++) != NULL)
|
||
{
|
||
if (*thisname != '\0')
|
||
{
|
||
printf("%s %% %s", i++ == 0 ? "" : ", ", thisname);
|
||
}
|
||
}
|
||
/* fill the "last" array with all -1s, to insure correct updating */
|
||
lp = lcpustates;
|
||
i = num_cpustates;
|
||
while (--i >= 0)
|
||
{
|
||
*lp++ = -1;
|
||
for (cpu = 0; cpu < n_cpus; ++cpu) {
|
||
if (n_cpus > 1)
|
||
printf("\nCPU%d states: ", cpu);
|
||
else
|
||
printf("\nCPU states: ");
|
||
lastline++;
|
||
i = 0;
|
||
names = cpustate_names;
|
||
while ((thisname = *names++) != NULL)
|
||
{
|
||
if (*thisname != '\0')
|
||
{
|
||
printf("%s %% %s", i++ == 0 ? "" : ", ", thisname);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
contrib/top/layout.h Wed Jun 14 01:45:28 2006 +0000 → contrib/top/layout.h Fri Jun 16 18:43:33 2006 +0900 | ||
---|---|---|
#define x_brkdn 15
|
||
#define y_brkdn 1
|
||
#define x_mem 5
|
||
#define y_mem 3
|
||
#define y_mem (y_cpustates+(smart_terminal?n_cpus:1))
|
||
#define x_swap 6
|
||
#define y_swap 4
|
||
#define y_message 5
|
||
#define y_swap (y_mem+1)
|
||
#define y_message (y_swap+1)
|
||
#define x_header 0
|
||
#define y_header 6
|
||
#define y_header (y_message+1)
|
||
#define x_idlecursor 0
|
||
#define y_idlecursor 5
|
||
#define y_procs 7
|
||
#define y_idlecursor (y_message)
|
||
#define y_procs (y_header+1)
|
||
#define y_cpustates 2
|
contrib/top/machine.h Wed Jun 14 01:45:28 2006 +0000 → contrib/top/machine.h Fri Jun 16 18:43:33 2006 +0900 | ||
---|---|---|
#define P_ACTIVE p_active
|
||
#endif
|
||
/* CPU1 states follow those of CPU0, and so on for SMP */
|
||
struct system_info
|
||
{
|
||
int last_pid;
|
contrib/top/top.c Wed Jun 14 01:45:28 2006 +0000 → contrib/top/top.c Fri Jun 16 18:43:33 2006 +0900 | ||
---|---|---|
int u_loadave();
|
||
int i_procstates();
|
||
int u_procstates();
|
||
int i_cpustates();
|
||
int u_cpustates();
|
||
int i_cpustates(struct system_info *);
|
||
int u_cpustates(struct system_info *);
|
||
int i_memory();
|
||
int u_memory();
|
||
int i_swap();
|
||
... | ... | |
/* pointers to display routines */
|
||
int (*d_loadave)() = i_loadave;
|
||
int (*d_procstates)() = i_procstates;
|
||
int (*d_cpustates)() = i_cpustates;
|
||
int (*d_cpustates)(struct system_info *) = i_cpustates;
|
||
int (*d_memory)() = i_memory;
|
||
int (*d_swap)() = i_swap;
|
||
int (*d_message)() = i_message;
|
||
int (*d_header)() = i_header;
|
||
int (*d_process)() = i_process;
|
||
int n_cpus = 0;
|
||
main(argc, argv)
|
||
... | ... | |
/* display the cpu state percentage breakdown */
|
||
if (dostates) /* but not the first time */
|
||
{
|
||
(*d_cpustates)(system_info.cpustates);
|
||
(*d_cpustates)(&system_info);
|
||
}
|
||
else
|
||
{
|
||
/* we'll do it next time */
|
||
if (smart_terminal)
|
||
{
|
||
z_cpustates();
|
||
z_cpustates(&system_info);
|
||
}
|
||
else
|
||
{
|
||
... | ... | |
{
|
||
d_loadave = u_loadave;
|
||
d_procstates = u_procstates;
|
||
d_cpustates = u_cpustates;
|
||
d_cpustates = i_cpustates;
|
||
d_memory = u_memory;
|
||
d_swap = u_swap;
|
||
d_message = u_message;
|
contrib/top/top.h Wed Jun 14 01:45:28 2006 +0000 → contrib/top/top.h Fri Jun 16 18:43:33 2006 +0900 | ||
---|---|---|
#define VERSION 3
|
||
/* Number of lines of header information on the standard screen */
|
||
#define Header_lines 7
|
||
#define Header_lines (7 + n_cpus - 1)
|
||
extern int n_cpus;
|
||
/* Maximum number of columns allowed for display */
|
||
#define MAX_COLS 128
|
usr.bin/top/machine.c Wed Jun 14 01:45:28 2006 +0000 → usr.bin/top/machine.c Fri Jun 16 18:43:33 2006 +0900 | ||
---|---|---|
/* these are for calculating cpu state percentages */
|
||
static struct kinfo_cputime cp_time, cp_old;
|
||
static struct kinfo_cputime *cp_time, *cp_old;
|
||
/* these are for detailing the process states */
|
||
... | ... | |
/* these are for detailing the cpu states */
|
||
#define CPU_STATES 5
|
||
int cpu_states[CPU_STATES];
|
||
int *cpu_states;
|
||
char *cpustatenames[CPU_STATES + 1] = {
|
||
"user", "nice", "system", "interrupt", "idle", NULL
|
||
};
|
||
... | ... | |
struct kinfo_cputime *old)
|
||
{
|
||
struct kinfo_cputime diffs;
|
||
int i;
|
||
uint64_t total_change, half_total;
|
||
/* initialization */
|
||
... | ... | |
size_t modelen;
|
||
struct passwd *pw;
|
||
if (n_cpus < 1) {
|
||
if (kinfo_get_cpus(&n_cpus))
|
||
err(1, "kinfo_get_cpus failed");
|
||
}
|
||
modelen = sizeof(smpmode);
|
||
if ((sysctlbyname("machdep.smp_active", &smpmode, &modelen, NULL, 0) < 0 &&
|
||
sysctlbyname("smp.smp_active", &smpmode, &modelen, NULL, 0) < 0) ||
|
||
... | ... | |
int mib[2];
|
||
struct timeval boottime;
|
||
size_t bt_size;
|
||
if (kinfo_get_sched_cputime(&cp_time))
|
||
err(1, "kinfo_get_sched_cputime failed");
|
||
size_t len;
|
||
int cpu;
|
||
if (cpu_states == NULL) {
|
||
cpu_states = malloc(sizeof(*cpu_states) * CPU_STATES * n_cpus);
|
||
if (cpu_states == NULL)
|
||
err(1, "malloc");
|
||
bzero(cpu_states, sizeof(*cpu_states) * CPU_STATES * n_cpus);
|
||
}
|
||
if (cp_time == NULL) {
|
||
cp_time = malloc(2 * n_cpus * sizeof(cp_time[0]));
|
||
if (cp_time == NULL)
|
||
err(1, "cp_time");
|
||
cp_old = cp_time + n_cpus;
|
||
len = n_cpus * sizeof(cp_old[0]);
|
||
if (sysctlbyname("kern.cputime", cp_old, &len, NULL, 0))
|
||
err(1, "kern.cputime");
|
||
}
|
||
len = n_cpus * sizeof(cp_time[0]);
|
||
bzero(cp_time, len);
|
||
if (sysctlbyname("kern.cputime", cp_time, &len, NULL, 0))
|
||
err(1, "kern.cputime");
|
||
getloadavg(si->load_avg, 3);
|
||
lastpid = 0;
|
||
/* convert cp_time counts to percentages */
|
||
cputime_percentages(cpu_states, &cp_time, &cp_old);
|
||
for (cpu = 0; cpu < n_cpus; ++cpu) {
|
||
cputime_percentages(cpu_states + cpu * n_cpus, &cp_time[cpu],
|
||
&cp_old[cpu]);
|
||
}
|
||
/* sum memory & swap statistics */
|
||
{
|