Hi,
The attached patch is an update over the previous one
(http://bugs.debian.org/406853#35 - sending to boinc_dev this time). It's
relatively ugly, unfortunately it's not easy to deal with proc/cpuinfo
without being so.
This patch does the following:
- Address a regression by witch all alpha and mips machines would have
been assigned a fixed string for vendor or model
- Add the necessary glue for hppa, sparc, ppc and ia64 (working around
for this particular arch a cpuinfo format change in 2.6.19), and modifying
the code in some places to avoid collecting unwanted garbage
- Add a default init value for host.m_cache to '-1' in order to avoid
random cache values for system on which cache info is unavailable
This patch doesn't fix the bug I reported in a previous mail, by which
host.p_model is too small to fit all parsed information.
The patch is relatively self-explanatory, I added a couple comments where
necessary, and people can find various cpuinfo files for testing purposes
here: http://www.pateam.org/archive/tmp/boinc/
The patch has been tested (thanks to the attached test program - which
doesn't do strip_whitespace(), btw) on a range of cpuinfo files coming
from:
ia64 (rx4610, rx2600, zx2000)
ppc (powermac g3 oldworld, powermac g5, CHRP pegasos 2)
alpha (AlphaServer DS10)
sparc (UltraSparc 30)
hppa (A500, B180, rp3440, J6000)
This patch doesn't pretend to be a perfect solution, it's merely trying
to point out potential workarounds. Let me know if this is any useful.
HTH
T-Bone
PS: Please CC-me in replies.
--
Thibaut VARENE
http://www.parisc-linux.org/~varenet/
#include <stdio.h>
#include <string.h>
#define false 0
#define true 1
#define bool int
#define strlcpy strncpy
int main(void)
{
char buf[256], features[1024], model_buf[1024];
bool vendor_found=false, model_found=false;
bool cache_found=false, features_found=false;
bool icache_found=false,dcache_found=false;
bool model_hack=false, vendor_hack=false;
int n;
int family=-1, model=-1, stepping=-1;
char p_vendor[256], p_model[256];
char buf2[256];
int m_cache=-1;
FILE* f = fopen("/proc/cpuinfo", "r");
if (!f) return;
#ifdef __mips__
strcpy(p_model, "MIPS ");
model_hack = true;
#elif __alpha__
strcpy(p_vendor, "HP (DEC) ");
vendor_hack = true;
#elif __hppa__
strcpy(p_vendor, "HP ");
vendor_hack = true;
#elif __ia64__
strcpy(p_model, "IA-64 ");
model_hack = true;
#endif
strcpy(features, "");
while (fgets(buf, 256, f)) {
//strip_whitespace(buf);
if (
/* there might be conflicts if we dont #ifdef */
#ifdef __ia64__
strstr(buf, "vendor : ")
#elif __hppa__
strstr(buf, "cpu\t\t: ")
#elif __powerpc__
strstr(buf, "machine\t\t: ")
#elif __sparc__
strstr(buf, "type\t\t: ")
#elif __alpha__
strstr(buf, "cpu\t\t\t: ")
#else
strstr(buf, "vendor_id\t: ") || strstr(buf, "system type\t\t: ")
#endif
) {
if (!vendor_hack && !vendor_found) {
vendor_found = true;
strlcpy(p_vendor, strchr(buf, ':') + 2, sizeof(p_vendor));
} else if (!vendor_found) {
vendor_found = true;
strlcpy(buf2, strchr(buf, ':') + 2, sizeof(p_vendor) - strlen(p_vendor) - 1);
strcat(p_vendor, buf2);
}
}
if (
#ifdef __ia64__
strstr(buf, "family : ") || strstr(buf, "model name : ")
#elif __powerpc__ || __sparc__
strstr(buf, "cpu\t\t: ")
#else
strstr(buf, "model name\t: ") || strstr(buf, "cpu model\t\t: ")
#endif
) {
if (!model_hack && !model_found) {
model_found = true;
#ifdef __powerpc__
char *coma = NULL;
if ((coma = strrchr(buf, ','))) { /* we have ", altivec supported" */
*coma = '\0'; /* strip the unwanted line */
strcpy(features, "altivec");
features_found = true;
}
#endif
strlcpy(p_model, strchr(buf, ':') + 2, sizeof(p_model));
} else if (!model_found) {
#ifdef __ia64__
/* depending on kernel version, family can be either
a number or a string. If number, we have a model name,
else we don't */
char *testc = NULL;
testc = strrchr(buf, ':')+2;
if (isdigit(*testc)) {
family = atoi(testc);
continue; /* skip this line */
}
#endif
model_found = true;
strlcpy(buf2, strchr(buf, ':') + 2, sizeof(p_model) - strlen(p_model) - 1);
strcat(p_model, buf2);
}
}
#ifndef __hppa__
/* XXX: hppa: "cpu family : PA-RISC 2.0" */
if (strstr(buf, "cpu family\t: ") && family<0) {
family = atoi(buf+strlen("cpu family\t: "));
}
/* XXX: hppa: "model : 9000/785/J6000" */
if (strstr(buf, "model\t\t: ") && model<0) {
model = atoi(buf+strlen("model\t\t: "));
}
/* ia64 */
if (strstr(buf, "model : ") && model<0) {
model = atoi(buf+strlen("model : "));
}
#endif
if (strstr(buf, "stepping\t: ") && stepping<0) {
stepping = atoi(buf+strlen("stepping\t: "));
}
#ifdef __hppa__
if (!icache_found && strstr(buf, "I-cache\t\t: ")) {
icache_found = true;
sscanf(buf, "I-cache\t\t: %d", &n);
m_cache += n*1024;
}
if (!dcache_found && strstr(buf, "D-cache\t\t: ")) {
dcache_found = true;
sscanf(buf, "D-cache\t\t: %d", &n);
m_cache += n*1024;
}
#elif __powerpc__
if (!cache_found && strstr(buf, "L2 cache\t: ")) {
cache_found = true;
sscanf(buf, "L2 cache\t: %d", &n);
m_cache = n*1024;
}
#else
if (!cache_found && (strstr(buf, "cache size\t: ") == buf)) {
cache_found = true;
sscanf(buf, "cache size\t: %d", &n);
m_cache = n*1024;
}
#endif
if (!features_found) {
// Some versions of the linux kernel call them flags,
// others call them features, so look for both.
if ((strstr(buf, "flags\t\t: ") == buf)) {
strlcpy(features, strchr(buf, ':') + 2, sizeof(features));
} else if ((strstr(buf, "features\t\t: ") == buf)) {
strlcpy(features, strchr(buf, ':') + 2, sizeof(features));
} else if ((strstr(buf, "features : ") == buf)) { /* ia64 */
strlcpy(features, strchr(buf, ':') + 2, sizeof(features));
}
if (strlen(features)) {
features_found = true;
}
}
}
strcpy(model_buf, p_model);
if (family>=0 || model>=0 || stepping>0) {
strcat(model_buf, " [");
if (family>=0) {
sprintf(buf, "Family %d ", family);
strcat(model_buf, buf);
}
if (model>=0) {
sprintf(buf, "Model %d ", model);
strcat(model_buf, buf);
}
if (stepping>=0) {
sprintf(buf, "Stepping %d", stepping);
strcat(model_buf, buf);
}
strcat(model_buf, "]");
}
if (strlen(features)) {
strcat(model_buf, "[");
strcat(model_buf, features);
strcat(model_buf, "]");
}
printf("p_vendor: %s\nm_cache: %d\nmodel_buf: %s\n", p_vendor, m_cache, model_buf);
return 0;
}
--- boinc-5.8.16/client/hostinfo_unix.C.orig 2007-03-01 17:10:08.000000000 +0100
+++ boinc-5.8.16/client/hostinfo_unix.C 2007-03-04 23:27:13.000000000 +0100
@@ -251,50 +251,137 @@
char buf[256], features[1024], model_buf[1024];
bool vendor_found=false, model_found=false;
bool cache_found=false, features_found=false;
+ bool icache_found=false,dcache_found=false;
+ bool model_hack=false, vendor_hack=false;
int n;
int family=-1, model=-1, stepping=-1;
+ char buf2[256];
FILE* f = fopen("/proc/cpuinfo", "r");
if (!f) return;
#ifdef __mips__
strcpy(host.p_model, "MIPS ");
- model_found = true;
+ model_hack = true;
#elif __alpha__
strcpy(host.p_vendor, "HP (DEC) ");
- vendor_found = true;
+ vendor_hack = true;
+#elif __hppa__
+ strcpy(host.p_vendor, "HP ");
+ vendor_hack = true;
+#elif __ia64__
+ strcpy(host.p_model, "IA-64 ");
+ model_hack = true;
#endif
+ host.m_cache=-1;
strcpy(features, "");
while (fgets(buf, 256, f)) {
strip_whitespace(buf);
- if (strstr(buf, "vendor_id\t: ") || strstr(buf, "system type\t\t: ")) {
- if (!vendor_found) {
+ if (
+ /* there might be conflicts if we dont #ifdef */
+#ifdef __ia64__
+ strstr(buf, "vendor : ")
+#elif __hppa__
+ strstr(buf, "cpu\t\t: ")
+#elif __powerpc__
+ strstr(buf, "machine\t\t: ")
+#elif __sparc__
+ strstr(buf, "type\t\t: ")
+#elif __alpha__
+ strstr(buf, "cpu\t\t\t: ")
+#else
+ strstr(buf, "vendor_id\t: ") || strstr(buf, "system type\t\t: ")
+#endif
+ ) {
+ if (!vendor_hack && !vendor_found) {
vendor_found = true;
strlcpy(host.p_vendor, strchr(buf, ':') + 2, sizeof(host.p_vendor));
+ } else if (!vendor_found) {
+ vendor_found = true;
+ strlcpy(buf2, strchr(buf, ':') + 2, sizeof(host.p_vendor) - strlen(host.p_vendor) - 1);
+ strcat(host.p_vendor, buf2);
}
}
- if (strstr(buf, "model name\t: ") || strstr(buf, "cpu model\t\t: ")) {
- if (!model_found) {
+ if (
+#ifdef __ia64__
+ strstr(buf, "family : ") || strstr(buf, "model name : ")
+#elif __powerpc__ || __sparc__
+ strstr(buf, "cpu\t\t: ")
+#else
+ strstr(buf, "model name\t: ") || strstr(buf, "cpu model\t\t: ")
+#endif
+ ) {
+ if (!model_hack && !model_found) {
model_found = true;
+#ifdef __powerpc__
+ char *coma = NULL;
+ if ((coma = strrchr(buf, ','))) { /* we have ", altivec supported" */
+ *coma = '\0'; /* strip the unwanted line */
+ strcpy(features, "altivec");
+ features_found = true;
+ }
+#endif
strlcpy(host.p_model, strchr(buf, ':') + 2, sizeof(host.p_model));
+ } else if (!model_found) {
+#ifdef __ia64__
+ /* depending on kernel version, family can be either
+ a number or a string. If number, we have a model name,
+ else we don't */
+ char *testc = NULL;
+ testc = strrchr(buf, ':')+2;
+ if (isdigit(*testc)) {
+ family = atoi(testc);
+ continue; /* skip this line */
+ }
+#endif
+ model_found = true;
+ strlcpy(buf2, strchr(buf, ':') + 2, sizeof(host.p_model) - strlen(host.p_model) - 1);
+ strcat(host.p_model, buf2);
}
}
+#ifndef __hppa__
+ /* XXX hppa: "cpu family\t: PA-RISC 2.0" */
if (strstr(buf, "cpu family\t: ") && family<0) {
family = atoi(buf+strlen("cpu family\t: "));
}
- if (strstr(buf, "model\t\t: ") && model<0) {
+ /* XXX hppa: "model\t\t: 9000/785/J6000" */
+ /* XXX alpha: "cpu model\t\t: EV6" -> ==buf necessary */
+ if ((strstr(buf, "model\t\t: ") == buf) && model<0) {
model = atoi(buf+strlen("model\t\t: "));
}
+ /* ia64 */
+ if (strstr(buf, "model : ") && model<0) {
+ model = atoi(buf+strlen("model : "));
+ }
+#endif
if (strstr(buf, "stepping\t: ") && stepping<0) {
stepping = atoi(buf+strlen("stepping\t: "));
}
+#ifdef __hppa__
+ if (!icache_found && strstr(buf, "I-cache\t\t: ")) {
+ icache_found = true;
+ sscanf(buf, "I-cache\t\t: %d", &n);
+ host.m_cache += n*1024;
+ }
+ if (!dcache_found && strstr(buf, "D-cache\t\t: ")) {
+ dcache_found = true;
+ sscanf(buf, "D-cache\t\t: %d", &n);
+ host.m_cache += n*1024;
+ }
+#elif __powerpc__
+ if (!cache_found && strstr(buf, "L2 cache\t: ")) {
+ cache_found = true;
+ sscanf(buf, "L2 cache\t: %d", &n);
+ host.m_cache = n*1024;
+ }
+#else
if (!cache_found && (strstr(buf, "cache size\t: ") == buf)) {
cache_found = true;
sscanf(buf, "cache size\t: %d", &n);
host.m_cache = n*1024;
}
-
+#endif
if (!features_found) {
// Some versions of the linux kernel call them flags,
// others call them features, so look for both.
@@ -303,6 +390,8 @@
strlcpy(features, strchr(buf, ':') + 2, sizeof(features));
} else if ((strstr(buf, "features\t\t: ") == buf)) {
strlcpy(features, strchr(buf, ':') + 2, sizeof(features));
+ } else if ((strstr(buf, "features : ") == buf)) { /* ia64 */
+ strlcpy(features, strchr(buf, ':') + 2, sizeof(features));
}
if (strlen(features)) {
features_found = true;