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;

Reply via email to