return strcmp(a->pattern, b->pattern);
}
+/*
+ * This function parses "key : value" from /proc/cpuinfo. The "key" describes CPU-type
+ * (type_patterns[]) or CPU specific (cpu_patterns[]) values.
+ *
+ * Note that s390-like "processor <n>:" lines are not suported here.
+ */
static int cpuinfo_parse_line( struct lscpu_cputype **ct,
struct lscpu_cpu **cpu,
const char *str)
buf[v - p] = '\0';
v++;
- fprintf(stderr, "key='%s', value='%s'\n", buf, v);
-
rtrim_whitespace((unsigned char *)buf);
/* search in cpu-types patterns */
return 0;
}
+static int is_processor_line(const char *str)
+{
+ const char *p;
+
+ if (!startswith(str, "processor "))
+ return 0;
+ p = str + 10;
+ while (*p && isdigit(*p))
+ p++;
+ if (*p == ':')
+ return 1;
+ return 0;
+}
+
+/*
+ * s390-like "processor <n>: value = xxx, value = yyy" lines parser.
+ */
+static int cpuinfo_parse_processor_line(struct lscpu_cpu **cpu, const char *str)
+{
+ const char *v;
+ char *end = NULL;
+ int n;
+
+ v = strchr(str, ' ');
+ if (!v)
+ return -EINVAL;
+ v++;
+ errno = 0;
+ n = strtol(v, &end, 10);
+ if (errno || !end || v == end || *end != ':')
+ return -EINVAL;
+
+ if (!*cpu)
+ *cpu = lscpu_new_cpu();
+
+ (*cpu)->logical_id = n;
+ return 0;
+}
+
int lscpu_read_cpuinfo(struct lscpu_cxt *cxt)
{
struct lscpu_cputype *type = NULL;
struct lscpu_cpu *cpu = NULL;
FILE *fp;
- size_t ncpus = 0;
char buf[BUFSIZ];
DBG(GATHER, ul_debugobj(cxt, "reading cpuinfo"));
if (fgets(buf, sizeof(buf), fp) != NULL)
p = skip_space(buf);
- if (p == NULL || (*buf && !*p)) { /* empty line */
- if (cpu) {
+ if (p == NULL || (*buf && !*p)) {
+ /*
+ * Blank line separates CPUs
+ */
+ if (cpu)
lscpu_add_cpu(cxt, cpu, type);
- ncpus++;
- } else if (type) {
+ else if (type) {
/* Generic non-cpu data. For some architectures
* cpuinfo contains description block (at the
* beginning of the file (IBM s390) or at the
break; /* fgets() returns nothing; EOF */
} else {
rtrim_whitespace((unsigned char *) buf);
- cpuinfo_parse_line(&type, &cpu, p);
+
+ if (is_processor_line(buf)) {
+ /* s390-like "processor <n>:" per line */
+ cpuinfo_parse_processor_line(&cpu, p);
+ if (cpu) {
+ lscpu_add_cpu(cxt, cpu, type);
+ lscpu_unref_cpu(cpu);
+ cpu = NULL;
+ }
+ } else
+ cpuinfo_parse_line(&type, &cpu, p);
}
} while (1);
fclose(fp);
DBG(GATHER, ul_debug("cpuinfo done: CPUs: %zu, types: %zu",
- ncpus, cxt->ncputypes));
+ cxt->ncpus, cxt->ncputypes));
return 0;
}
(ct->nsockets ?: 1) *
(ct->ncores ?: 1) * nthreads;
- DBG(TYPE, ul_debugobj(ct, " nthreads: %d", ct->nthreads));
+ DBG(TYPE, ul_debugobj(ct, " nthreads: %d (per core: %d)", ct->nthreads, nthreads));
DBG(TYPE, ul_debugobj(ct, " ncores: %d", ct->ncores));
DBG(TYPE, ul_debugobj(ct, " nsockets: %d", ct->nsockets));
DBG(TYPE, ul_debugobj(ct, " nbooks: %d", ct->nbooks));