cpustat?
YONETANI Tomokazu
qhwt+dfly at les.ath.cx
Fri Jun 16 02:52:21 PDT 2006
> Danial Thom wrote:
> > I remember some chatter about cpustat but i don't
> > see it in 1.5.3-PREVIEW, and I don't see that top
> > shows the cpu breakdown. What's the status of
> > this, or what's the utility of choice for
> > monitoring the allocation of cpu resources?
>
> cpustat is in src/test/pcpu/cpustat.c and yes, it hasn't been merged
> into top yet, maybe you want to do it ;)
No response from Danial because top is too messy to play with? :)
Attached and also available at:
http://les.ath.cx/DragonFly/top-pcpu.diff
Regards.
diff -r ddfcf59ccfb0 contrib/top/display.c
--- a/contrib/top/display.c Wed Jun 14 01:45:28 2006 +0000
+++ b/contrib/top/display.c Fri Jun 16 18:43:33 2006 +0900
@@ -75,7 +75,6 @@ static int num_swap;
static int num_swap;
static int *lprocstates;
-static int *lcpustates;
static int *lmemory;
static int *lswap;
@@ -154,7 +153,6 @@ struct statics *statics;
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;
@@ -372,141 +370,68 @@ int *brkdn;
* 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);
+ }
+ }
}
}
diff -r ddfcf59ccfb0 contrib/top/layout.h
--- a/contrib/top/layout.h Wed Jun 14 01:45:28 2006 +0000
+++ b/contrib/top/layout.h Fri Jun 16 18:43:33 2006 +0900
@@ -16,14 +16,14 @@
#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
diff -r ddfcf59ccfb0 contrib/top/machine.h
--- a/contrib/top/machine.h Wed Jun 14 01:45:28 2006 +0000
+++ b/contrib/top/machine.h Fri Jun 16 18:43:33 2006 +0900
@@ -33,6 +33,7 @@ struct statics
#define P_ACTIVE p_active
#endif
+/* CPU1 states follow those of CPU0, and so on for SMP */
struct system_info
{
int last_pid;
diff -r ddfcf59ccfb0 contrib/top/top.c
--- a/contrib/top/top.c Wed Jun 14 01:45:28 2006 +0000
+++ b/contrib/top/top.c Fri Jun 16 18:43:33 2006 +0900
@@ -114,8 +114,8 @@ int u_loadave();
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();
@@ -130,13 +130,14 @@ int u_process();
/* 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)
@@ -583,14 +584,14 @@ restart:
/* 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
{
@@ -663,7 +664,7 @@ restart:
{
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;
diff -r ddfcf59ccfb0 contrib/top/top.h
--- a/contrib/top/top.h Wed Jun 14 01:45:28 2006 +0000
+++ b/contrib/top/top.h Fri Jun 16 18:43:33 2006 +0900
@@ -8,7 +8,8 @@
#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
diff -r ddfcf59ccfb0 usr.bin/top/machine.c
--- a/usr.bin/top/machine.c Wed Jun 14 01:45:28 2006 +0000
+++ b/usr.bin/top/machine.c Fri Jun 16 18:43:33 2006 +0900
@@ -133,7 +133,7 @@ static int ccpu;
/* 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 */
@@ -146,7 +146,7 @@ char *procstatenames[] = {
/* 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
};
@@ -195,7 +195,6 @@ cputime_percentages(int out[CPU_STATES],
struct kinfo_cputime *old)
{
struct kinfo_cputime diffs;
- int i;
uint64_t total_change, half_total;
/* initialization */
@@ -236,6 +235,10 @@ machine_init(struct statics *statics)
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) ||
@@ -322,16 +325,40 @@ get_system_info(struct system_info *si)
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 */
{
More information about the Submit
mailing list