diff --git a/ChangeLog b/ChangeLog index 22d0666f..84787192 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ # $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) diff --git a/README b/README index 779e1606..d66a21cc 100644 --- a/README +++ b/README @@ -551,10 +551,14 @@ VARIABLES $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 @@ -996,7 +1000,7 @@ VARIABLES 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. diff --git a/doc/conky.1 b/doc/conky.1 index 177dbe26..5b9a15ee 100644 --- a/doc/conky.1 +++ b/doc/conky.1 @@ -501,12 +501,16 @@ Same as execigraph, but takes an interval arg graphs values 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 @@ -871,7 +875,7 @@ Total download, overflows at 4 GB on Linux with 32-bit arch and there doesn't se .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 diff --git a/doc/variables.xml b/doc/variables.xml index 732c45c3..d9abf2aa 100644 --- a/doc/variables.xml +++ b/doc/variables.xml @@ -365,17 +365,23 @@ + - Returns CPU frequency in MHz + Returns CPU #n's frequency in MHz. CPUs are + counted from 1. If omitted, the parameter + defaults to 1. + - Returns CPU frequency in GHz + Returns CPU #n's frequency in GHz. CPUs are + counted from 1. If omitted, the parameter + defaults to 1. @@ -1163,7 +1169,7 @@ - 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. diff --git a/src/conky.c b/src/conky.c index e2df1736..73076337 100644 --- a/src/conky.c +++ b/src/conky.c @@ -1978,8 +1978,49 @@ static struct text_object *construct_text_object(const char *s, const char *arg, 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); @@ -3090,10 +3131,10 @@ static void generate_text_internal(char *p, int p_max_size, struct text_object * 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) { diff --git a/src/conky.h b/src/conky.h index da9e9417..30db1e34 100644 --- a/src/conky.h +++ b/src/conky.h @@ -461,7 +461,7 @@ void update_cpu_usage(void); 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, diff --git a/src/linux.c b/src/linux.c index 240cae58..673667bd 100644 --- a/src/linux.c +++ b/src/linux.c @@ -834,25 +834,37 @@ void get_freq_dynamic( char * p_client_buffer, size_t client_buffer_size, char * 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. */ @@ -865,18 +877,20 @@ void get_freq( char * p_client_buffer, size_t client_buffer_size, char * p_forma 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) @@ -890,6 +904,11 @@ void get_freq( char * p_client_buffer, size_t client_buffer_size, char * p_forma #endif break; } + if (strncmp(s, "processor", 9) == 0) { + cpu--; + continue; + } + } fclose(f);