On Thu, 24 Mar 2011, Stuart Henderson wrote:
If you run some automated clock control (like apmd -C), you never
know to what clock the cpu-time statistics in top(1) and systat(1)
are related to.
You still don't exactly, as top(1)'s cpu-time statistics are over
an interval, whereas hw.cpuspeed is instantaneous. I do think it may
be useful to display this information somewhere, but I'm not convinced
that top(1) is the right place.
I am fully aware that it is not always completly exact, and but on the
other hand the CPU clock rate doesn't change immediately, it takes at least
5 seconds to drop/rise after the CPU load changes. At least on my Pentium-M
based Thinkpad, where I run apmd -C. Much better displaying this than
nothing, I believe.
I added it to top(1) (and would like to add it to systat(1) too), so as to
be able to "read" the other performance statistics (approximately) right,
without the need to switch to other virtual console/window/terminal every
a few seconds for other utility, like apm(1) in a loop.
Anyway, HW_CPUSPEED is of type int, same as is HW_SETPERF. Not int[],
only int. How could the individual cores be reported and controlled?
Obviously they can't at present, the kernel would need to be
extended. But if you're considering how the display might look with
a hypothetical 10GHz processor, why wouldn't you want to think about
how things could work with current cpu features?
As I said, I was not aware of this trait of the new i-series Intel CPU's
and others. At least, the patch will work well and be useful on all
hardware except the latest, for which the kernel is not yet extended
anyway.
Below, there is the fixed and slightly improved version of the patch, if
somebody thinks it is still useful. But from point of view of our
discussion above, it remains the same, of course.
Regards,
David
Index: src/usr.bin/top/display.c
===================================================================
RCS file: /cvs/src/usr.bin/top/display.c,v
retrieving revision 1.40
diff -u -p -u -r1.40 display.c
--- src/usr.bin/top/display.c 23 Apr 2010 09:26:13 -0000 1.40
+++ src/usr.bin/top/display.c 24 Mar 2011 12:17:57 -0000
@@ -205,7 +205,7 @@ display_init(struct statics * statics)
}
void
-i_loadave(pid_t mpid, double *avenrun)
+i_loadave(pid_t mpid, double *avenrun, int cpuspeed)
{
if (screen_length > 1 || !smart_terminal) {
int i;
@@ -220,6 +220,9 @@ i_loadave(pid_t mpid, double *avenrun)
for (i = 0; i < 3; i++)
printwp("%c %5.2f", i == 0 ? ':' : ',', avenrun[i]);
+
+ if (cpuspeed != 0)
+ printwp(" / %4d MHz", cpuspeed);
}
}
@@ -238,16 +241,25 @@ void
i_timeofday(time_t * tod)
{
static char buf[30];
+ int bufspace;
if (buf[0] == '\0')
gethostname(buf, sizeof(buf));
if (screen_length > 1 || !smart_terminal) {
if (smart_terminal) {
- move(0, screen_width - 8 - strlen(buf) - 1);
+ /* Load averages and space fill up 35 chars,
+ * cpu speed and space fill up 11 chars,
+ * space and clock fill up 9 chars.
+ */
+ bufspace = screen_width - 35 - 11 - 9;
+ if (bufspace < 0)
+ bufspace = 0;
+ move(0, screen_width - 8 - bufspace - 1);
} else {
if (fputs(" ", stdout) == EOF)
exit(1);
+ bufspace = 24;
}
#ifdef DEBUG
{
@@ -256,7 +268,7 @@ i_timeofday(time_t * tod)
addstrp(foo);
}
#endif
- printwp("%s %-8.8s", buf, &(ctime(tod)[11]));
+ printwp("%*.*s %-8.8s", bufspace, bufspace, buf,
&(ctime(tod)[11]));
putn();
}
}
Index: src/usr.bin/top/display.h
===================================================================
RCS file: /cvs/src/usr.bin/top/display.h,v
retrieving revision 1.11
diff -u -p -u -r1.11 display.h
--- src/usr.bin/top/display.h 22 Nov 2007 11:01:04 -0000 1.11
+++ src/usr.bin/top/display.h 24 Mar 2011 12:17:57 -0000
@@ -35,7 +35,7 @@
/* prototypes */
int display_resize(void);
-void i_loadave(int, double *);
+void i_loadave(int, double *, int);
void u_loadave(int, double *);
void i_timeofday(time_t *);
void i_procstates(int, int *);
Index: src/usr.bin/top/machine.c
===================================================================
RCS file: /cvs/src/usr.bin/top/machine.c,v
retrieving revision 1.67
diff -u -p -u -r1.67 machine.c
--- src/usr.bin/top/machine.c 26 Apr 2010 00:30:58 -0000 1.67
+++ src/usr.bin/top/machine.c 24 Mar 2011 12:17:58 -0000
@@ -204,6 +204,8 @@ format_header(char *uname_field)
void
get_system_info(struct system_info *si)
{
+ static int cpuspeed_mib[] = {CTL_HW, HW_CPUSPEED};
+ int cpuspeed;
static int sysload_mib[] = {CTL_VM, VM_LOADAVG};
static int vmtotal_mib[] = {CTL_VM, VM_METER};
struct loadavg sysload;
@@ -212,6 +214,13 @@ get_system_info(struct system_info *si)
size_t size;
int i;
int64_t *tmpstate;
+
+ /* get this value first */
+ size = sizeof(sysload);
+ if (sysctl(cpuspeed_mib, 2, &cpuspeed, &size, NULL, 0) < 0)
+ si->cpuspeed = 0;
+ else
+ si->cpuspeed = cpuspeed;
if (ncpu > 1) {
int cp_time_mib[] = {CTL_KERN, KERN_CPTIME2, /*fillme*/0};
Index: src/usr.bin/top/machine.h
===================================================================
RCS file: /cvs/src/usr.bin/top/machine.h,v
retrieving revision 1.15
diff -u -p -u -r1.15 machine.h
--- src/usr.bin/top/machine.h 29 May 2007 00:56:56 -0000 1.15
+++ src/usr.bin/top/machine.h 24 Mar 2011 12:17:58 -0000
@@ -50,6 +50,7 @@ struct statics {
struct system_info {
pid_t last_pid;
+ int cpuspeed;
double load_avg[NUM_AVERAGES];
int p_total;
int p_active; /* number of procs considered
Index: src/usr.bin/top/top.1
===================================================================
RCS file: /cvs/src/usr.bin/top/top.1,v
retrieving revision 1.57
diff -u -p -u -r1.57 top.1
--- src/usr.bin/top/top.1 10 Aug 2010 20:34:16 -0000 1.57
+++ src/usr.bin/top/top.1 24 Mar 2011 12:17:58 -0000
@@ -370,6 +370,7 @@ about the state of the system, including
.\" the last process ID assigned to a process,
.\" (on most systems),
the three load average numbers,
+the current CPU frequency,
the hostname,
the current time,
the number of existing processes,
Index: src/usr.bin/top/top.c
===================================================================
RCS file: /cvs/src/usr.bin/top/top.c,v
retrieving revision 1.75
diff -u -p -u -r1.75 top.c
--- src/usr.bin/top/top.c 24 Apr 2010 22:02:14 -0000 1.75
+++ src/usr.bin/top/top.c 24 Mar 2011 12:17:58 -0000
@@ -434,10 +434,10 @@ restart:
processes = get_process_info(&system_info, &ps,
proc_compares[order_index]);
- /* display the load averages */
- i_loadave(system_info.last_pid, system_info.load_avg);
+ /* display the load averages and current cpu speed */
+ i_loadave(system_info.last_pid, system_info.load_avg,
system_info.cpuspeed);
- /* display the current time */
+ /* display the hostname and current time */
/* this method of getting the time SHOULD be fairly portable */
time(&curr_time);
i_timeofday(&curr_time);