// This file is part of BOINC. // http://boinc.berkeley.edu // Copyright (C) 2008 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License // as published by the Free Software Foundation, // either version 3 of the License, or (at your option) any later version. // // BOINC is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with BOINC. If not, see . #include #include #include #include #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 (EXIT_FAILURE); #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; #elif __arm__ strcpy(p_vendor, "ARM "); vendor_hack = vendor_found = 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: ") #elif __arm__ strstr(buf, "CPU architecture: ") #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: ") #elif __arm__ strstr(buf, "Processor\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)); } else if ((strstr(buf, "Features\t: ") == buf)) { /* arm */ strlcpy(features, strchr(buf, ':') + 2, sizeof(features)); } if (strlen(features)) { features_found = true; } } } safe_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 ); fclose(f); }