|
@@ -0,0 +1,134 @@
|
|
|
+#include <stdio.h>
|
|
|
+#include <string.h>
|
|
|
+#include <assert.h>
|
|
|
+
|
|
|
+#define CPUINFO_FILE "/proc/cpuinfo"
|
|
|
+#define BUFFSIZE 2048
|
|
|
+
|
|
|
+/* vendor_id, model_name size reference Linux kernel struct cpuinfo_x86
|
|
|
+ * (see Linux's arch/x86/include/asm/processor.h) */
|
|
|
+struct cpuinfo {
|
|
|
+ int processor;
|
|
|
+ char vendor_id[16];
|
|
|
+ int cpu_family;
|
|
|
+ int model;
|
|
|
+ char model_name[64];
|
|
|
+ int stepping;
|
|
|
+ int core_id;
|
|
|
+ int cpu_cores;
|
|
|
+};
|
|
|
+
|
|
|
+static void init_cpuinfo(struct cpuinfo *ci) {
|
|
|
+ ci->processor = -1;
|
|
|
+ memset(&ci->vendor_id, 0, sizeof(ci->vendor_id));
|
|
|
+ ci->cpu_family = -1;
|
|
|
+ ci->model = -1;
|
|
|
+ memset(&ci->model_name, 0, sizeof(ci->model_name));
|
|
|
+ ci->stepping = -1;
|
|
|
+ ci->core_id = -1;
|
|
|
+ ci->cpu_cores = -1;
|
|
|
+}
|
|
|
+
|
|
|
+static int parse_line(char *line, struct cpuinfo *ci) {
|
|
|
+ char *k, *v, *p;
|
|
|
+
|
|
|
+ if ((p = strchr(line, ':')) == NULL)
|
|
|
+ goto fmt_err;
|
|
|
+
|
|
|
+ /* if the line does not have value string, p[1] should be '\n', otherwise
|
|
|
+ * p[1] should be ' ' */
|
|
|
+ if (p[1] == '\n' && !p[2])
|
|
|
+ return 0; /* No value string */
|
|
|
+
|
|
|
+ /* ':' should always be followed by a space */
|
|
|
+ if (p[1] != ' ')
|
|
|
+ goto fmt_err;
|
|
|
+
|
|
|
+ /* skip ": " to get value string */
|
|
|
+ v = p + 2;
|
|
|
+
|
|
|
+ /* get key string */
|
|
|
+ *p = '\0';
|
|
|
+ if ((p = strchr(line, '\t')) != NULL)
|
|
|
+ *p = '\0';
|
|
|
+ k = line;
|
|
|
+
|
|
|
+ if (!strcmp(k, "processor")) {
|
|
|
+ sscanf(v, "%d\n", &ci->processor);
|
|
|
+ } else if (!strcmp(k, "cpu family")) {
|
|
|
+ sscanf(v, "%d\n", &ci->cpu_family);
|
|
|
+ } else if (!strcmp(k, "model")) {
|
|
|
+ sscanf(v, "%d\n", &ci->model);
|
|
|
+ } else if (!strcmp(k, "stepping")) {
|
|
|
+ sscanf(v, "%d\n", &ci->stepping);
|
|
|
+ } else if (!strcmp(k, "core id")) {
|
|
|
+ sscanf(v, "%d\n", &ci->core_id);
|
|
|
+ } else if (!strcmp(k, "cpu cores")) {
|
|
|
+ sscanf(v, "%d\n", &ci->cpu_cores);
|
|
|
+ } else if (!strcmp(k, "vendor_id")) {
|
|
|
+ snprintf(ci->vendor_id, sizeof(ci->vendor_id), "%s", v);
|
|
|
+ } else if (!strcmp(k, "model name")) {
|
|
|
+ snprintf(ci->model_name, sizeof(ci->model_name), "%s", v);
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+
|
|
|
+fmt_err:
|
|
|
+ fprintf(stderr, "format error in line: %s\n", line);
|
|
|
+ return -1;
|
|
|
+};
|
|
|
+
|
|
|
+static int check_cpuinfo(struct cpuinfo *ci) {
|
|
|
+ if (ci->processor == -1) {
|
|
|
+ fprintf(stderr, "Could not get cpu index\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ if (ci->core_id == -1) {
|
|
|
+ fprintf(stderr, "Could not get core id\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ if (ci->cpu_cores == -1) {
|
|
|
+ fprintf(stderr, "Could not get cpu cores\n");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+int main (int argc, char *argv[]) {
|
|
|
+ FILE *fp = NULL;
|
|
|
+ char line[BUFFSIZE];
|
|
|
+ struct cpuinfo ci;
|
|
|
+ int cpu_cnt = 0, rv = 0;
|
|
|
+
|
|
|
+ init_cpuinfo(&ci);
|
|
|
+
|
|
|
+ if ((fp = fopen(CPUINFO_FILE, "r")) == NULL) {
|
|
|
+ perror("fopen");
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ while (fgets(line, sizeof(line), fp) != NULL) {
|
|
|
+ if (line[0] == '\n') {
|
|
|
+ if ((rv = check_cpuinfo(&ci)) != 0)
|
|
|
+ break;
|
|
|
+ cpu_cnt++;
|
|
|
+ init_cpuinfo(&ci);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if ((rv = parse_line(line, &ci)) != 0)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ fclose(fp);
|
|
|
+
|
|
|
+ if (rv != 0)
|
|
|
+ return 1;
|
|
|
+
|
|
|
+ if (cpu_cnt == 0) {
|
|
|
+ fprintf(stderr, "Could not get online cpu info.\n");
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ printf("cpuinfo test passed\n");
|
|
|
+ return 0;
|
|
|
+}
|