# $Id$
+2006-05-21
+ * SMP support for $freq and $freq_g (thanks to Peter Tarjan for the
+ patch)
+
2006-05-17
* Fixed issue with graphs not reaching all the way to the borders
(sf.net bug 1470480)
$color)
- freq Returns CPU frequency in MHz
+ freq (n)
+ Returns CPU #n's frequency in MHz. CPUs are counted from 1. If
+ omitted, the parameter defaults to 1.
- freq_g Returns CPU frequency in GHz
+ freq_g (n)
+ Returns CPU #n's frequency in GHz. CPUs are counted from 1. If
+ omitted, the parameter defaults to 1.
freq_dyn
This takes arguments in the form:top (name) (number) Basically,
processes are ranked from highest to lowest in terms of cpu
usage, which is what (num) represents. The types are: "name",
- "pid", "cpu", and mem". There can be a max of 10 processes
+ "pid", "cpu", and "mem". There can be a max of 10 processes
listed.
Specify a different font. This new font will apply to the current line and everything following. You can use a $font with no arguments to change back to the default font (much like with $color)
.TP
-\fBfreq\fR
-Returns CPU frequency in MHz
+\fBfreq\fR \fB(n)\fR
+Returns CPU #n's frequency in MHz. CPUs are
+counted from 1. If omitted, the parameter
+defaults to 1.
.TP
-\fBfreq_g\fR
-Returns CPU frequency in GHz
+\fBfreq_g\fR \fB(n)\fR
+Returns CPU #n's frequency in GHz. CPUs are
+counted from 1. If omitted, the parameter
+defaults to 1.
.TP
\fBfreq_dyn\fR
.TP
\fBtop\fR \fBtype, num\fR
-This takes arguments in the form:top (name) (number) Basically, processes are ranked from highest to lowest in terms of cpu usage, which is what (num) represents. The types are: "name", "pid", "cpu", and mem". There can be a max of 10 processes listed.
+This takes arguments in the form:top (name) (number) Basically, processes are ranked from highest to lowest in terms of cpu usage, which is what (num) represents. The types are: "name", "pid", "cpu", and "mem". There can be a max of 10 processes listed.
.TP
\fBtop_mem\fR \fBtype, num\fR
<varlistentry>
<term>
<command><option>freq</option></command>
+ <option>(n)</option>
</term>
<listitem>
- Returns CPU frequency in MHz
+ Returns CPU #n's frequency in MHz. CPUs are
+ counted from 1. If omitted, the parameter
+ defaults to 1.
<para></para></listitem>
</varlistentry>
<varlistentry>
<term>
<command><option>freq_g</option></command>
+ <option>(n)</option>
</term>
<listitem>
- Returns CPU frequency in GHz
+ Returns CPU #n's frequency in GHz. CPUs are
+ counted from 1. If omitted, the parameter
+ defaults to 1.
<para></para></listitem>
</varlistentry>
<option>type, num</option>
</term>
<listitem>
- This takes arguments in the form:top (name) (number) Basically, processes are ranked from highest to lowest in terms of cpu usage, which is what (num) represents. The types are: "name", "pid", "cpu", and mem". There can be a max of 10 processes listed.
+ This takes arguments in the form:top (name) (number) Basically, processes are ranked from highest to lowest in terms of cpu usage, which is what (num) represents. The types are: "name", "pid", "cpu", and "mem". There can be a max of 10 processes listed.
<para></para></listitem>
</varlistentry>
OBJ(acpitemp, 0) obj->data.i = open_acpi_temperature(arg);
END OBJ(acpitempf, 0) obj->data.i = open_acpi_temperature(arg);
END OBJ(acpiacadapter, 0)
- END OBJ(freq, 0);
+#if defined(__linux__)
+ END OBJ(freq, 0)
+/* gives an 'implicit declaration' warning when compiled
+ not nice but as of now it shouldn't be a problem: only
+ linux.c and freebsd.c have get_freq functions and both platforms
+ have their respective get_cpu_count() functions (ptarjan) */
+ get_cpu_count();
+ if (!arg
+ || !isdigit(arg[0])
+ || strlen(arg) >=2
+ || atoi(&arg[0])==0
+ || (unsigned int)atoi(&arg[0])>info.cpu_count)
+ {
+ obj->data.cpu_index=1;
+ ERR("freq: Invalid CPU number or you don't have that many CPUs! Displaying the clock for CPU 1.");
+ }
+ else
+ {
+ obj->data.cpu_index=atoi(&arg[0]);
+ }
+ END OBJ(freq_g, 0)
+/* gives an 'implicit declaration' warning when compiled
+ not nice but as of now it shouldn't be a problem: only
+ linux.c and freebsd.c have get_freq functions and both platforms
+ have their respective get_cpu_count() functions (ptarjan) */
+ get_cpu_count();
+ if (!arg
+ || !isdigit(arg[0])
+ || strlen(arg) >=2
+ || atoi(&arg[0])==0
+ || (unsigned int)atoi(&arg[0])>info.cpu_count)
+ {
+ obj->data.cpu_index=1;
+ ERR("freq_g: Invalid CPU number or you don't have that many CPUs! Displaying the clock for CPU 1.");
+ }
+ else
+ {
+ obj->data.cpu_index=atoi(&arg[0]);
+ }
+#else
+ END OBJ(freq, 0);
END OBJ(freq_g, 0);
+#endif /* __linux__ */
END OBJ(freq_dyn, 0);
END OBJ(freq_dyn_g, 0);
END OBJ(acpifan, 0);
i)+ 40) * 9.0 / 5 - 40));
}
OBJ(freq) {
- get_freq(p, p_max_size, "%.0f", 1); /* pk */
+ get_freq(p, p_max_size, "%.0f", 1, obj->data.cpu_index); /* pk */
}
OBJ(freq_g) {
- get_freq(p, p_max_size, "%'.2f", 1000); /* pk */
+ get_freq(p, p_max_size, "%'.2f", 1000, obj->data.cpu_index); /* pk */
}
OBJ(freq_dyn) {
if (use_spacer) {
void update_total_processes(void);
void update_running_processes(void);
void update_i8k(void);
-void get_freq( char *, size_t, char *, int ); /* pk */
+void get_freq( char *, size_t, char *, int, unsigned int ); /* pk */
void get_freq_dynamic( char *, size_t, char *, int ); /* pk */
void update_load_average();
int open_i2c_sensor(const char *dev, const char *type, int n, int *div,
snprintf( p_client_buffer, client_buffer_size, p_format, (float)((cycles[1] - cycles[0]) / microseconds) / divisor );
return;
#else
- get_freq( p_client_buffer, client_buffer_size, p_format, divisor );
+/* FIXME: hardwired: get freq for first cpu!
+ this whole function needs to be rethought and redone for
+ multi-cpu/multi-core/multi-threaded environments and
+ arbitrary combinations thereof
+*/
+ get_freq( p_client_buffer, client_buffer_size, p_format, divisor, 1 );
return;
#endif
}
-#define CPUFREQ_CURRENT "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq"
+
+#define CPUFREQ_PREFIX "/sys/devices/system/cpu"
+#define CPUFREQ_POSTFIX "cpufreq/scaling_cur_freq"
/* return system frequency in MHz (use divisor=1) or GHz (use divisor=1000) */
-void get_freq( char * p_client_buffer, size_t client_buffer_size, char * p_format, int divisor )
+void get_freq( char * p_client_buffer, size_t client_buffer_size, char * p_format, int divisor, unsigned int cpu )
{
FILE *f;
char frequency[32];
char s[256];
double freq = 0;
+ char current_freq_file[128];
+
+ cpu--;
+ snprintf(current_freq_file, 127, "%s/cpu%d/%s",
+ CPUFREQ_PREFIX, cpu, CPUFREQ_POSTFIX);
if ( !p_client_buffer || client_buffer_size <= 0 || !p_format || divisor <= 0 )
return;
- f = fopen(CPUFREQ_CURRENT, "r");
+ f = fopen(current_freq_file, "r");
if (f) {
/* if there's a cpufreq /sys node, read the current frequency from this node;
* divide by 1000 to get Mhz. */
return;
}
+ cpu++;
f = fopen("/proc/cpuinfo", "r"); //open the CPU information file
if (!f)
return;
while (fgets(s, sizeof(s), f) != NULL){ //read the file
+
#if defined(__i386) || defined(__x86_64)
- if (strncmp(s, "cpu MHz", 7) == 0) { //and search for the cpu mhz
+ if (strncmp(s, "cpu MHz", 7) == 0 && cpu == 0) { //and search for the cpu mhz
#else
#if defined(__alpha)
- if (strncmp(s, "cycle frequency [Hz]", 20) == 0) { // different on alpha
+ if (strncmp(s, "cycle frequency [Hz]", 20) == 0 && cpu == 0) { // different on alpha
#else
- if (strncmp(s, "clock", 5) == 0) { // this is different on ppc for some reason
+ if (strncmp(s, "clock", 5) == 0 && cpu == 0) { // this is different on ppc for some reason
#endif // defined(__alpha)
#endif // defined(__i386) || defined(__x86_64)
#endif
break;
}
+ if (strncmp(s, "processor", 9) == 0) {
+ cpu--;
+ continue;
+ }
+
}
fclose(f);