};
struct lscpu_cxt {
- const char *prefix; /* path to /sys and /proc snapshot or NULL */
+ int maxcpus; /* size in bits of kernel cpu mask */
+ const char *prefix; /* path to /sys and /proc snapshot or NULL */
struct path_cxt *syscpu; /* _PATH_SYS_CPU path handler */
struct path_cxt *procfs; /* /proc path handler */
size_t ncpus;
struct lscpu_cpu **cpus;
+ /*
+ * All maps are sequentially indexed (0..ncpuspos), the array index
+ * does not have match with cpuX number as presented by kernel. You
+ * have to use real_cpu_num() to get the real cpuX number.
+ *
+ * For example, the possible system CPUs are: 1,3,5, it means that
+ * ncpuspos=3, so all arrays are in range 0..3.
+ */
+ size_t ncpuspos; /* maximal possible CPUs */
+ int *idx2cpunum; /* mapping index to CPU num */
+
+ size_t npresents;
+ cpu_set_t *present; /* mask with present CPUs */
+
+ size_t nonlines; /* aka number of trhreads */
+ cpu_set_t *online; /* mask with online CPUs */
+
struct lscpu_arch *arch;
unsigned int noalive;
int lscpu_read_cpuinfo(struct lscpu_cxt *cxt);
int lscpu_read_architecture(struct lscpu_cxt *cxt);
+int lscpu_read_cpulists(struct lscpu_cxt *cxt);
struct lscpu_cpu *lscpu_new_cpu(void);
void lscpu_ref_cpu(struct lscpu_cpu *cpu);
return 0;
}
+int lscpu_read_cpulists(struct lscpu_cxt *cxt)
+{
+ size_t maxn;
+ size_t setsize;
+ cpu_set_t *cpuset = NULL;
+
+ assert(cxt);
+ DBG(GATHER, ul_debugobj(cxt, "reading cpulists"));
+
+ if (ul_path_read_s32(cxt->syscpu, &cxt->maxcpus, "kernel_max") == 0)
+ /* note that kernel_max is maximum index [NR_CPUS-1] */
+ cxt->maxcpus += 1;
+
+ else if (!cxt->noalive)
+ /* the root is '/' so we are working with data from the current kernel */
+ cxt->maxcpus = get_max_number_of_cpus();
+
+ if (cxt->maxcpus <= 0)
+ /* error or we are reading some /sys snapshot instead of the
+ * real /sys, let's use any crazy number... */
+ cxt->maxcpus = 2048;
+
+ maxn = cxt->maxcpus;
+ setsize = CPU_ALLOC_SIZE(maxn);
+
+ if (ul_path_readf_cpulist(cxt->syscpu, &cpuset, maxn, "possible") == 0) {
+ size_t num, idx;
+
+ cxt->ncpuspos = CPU_COUNT_S(setsize, cpuset);
+ cxt->idx2cpunum = xcalloc(cxt->ncpuspos, sizeof(int));
+
+ for (num = 0, idx = 0; num < maxn; num++) {
+ if (CPU_ISSET_S(num, setsize, cpuset))
+ cxt->idx2cpunum[idx++] = num;
+ }
+ cpuset_free(cpuset);
+ cpuset = NULL;
+ } else
+ err(EXIT_FAILURE, _("failed to determine number of CPUs: %s"),
+ _PATH_SYS_CPU "/possible");
+
+
+ /* get mask for present CPUs */
+ if (ul_path_readf_cpulist(cxt->syscpu, &cxt->present, maxn, "present") == 0)
+ cxt->npresents = CPU_COUNT_S(setsize, cxt->present);
+
+ /* get mask for online CPUs */
+ if (ul_path_readf_cpulist(cxt->syscpu, &cxt->online, maxn, "online") == 0)
+ cxt->nonlines = CPU_COUNT_S(setsize, cxt->online);
+
+ return 0;
+}
+
#ifdef TEST_PROGRAM_CPUTYPE
/* TODO: move to lscpu.c */
struct lscpu_cxt *lscpu_new_context(void)
for (i = 0; i < cxt->ncputypes; i++)
lscpu_unref_cputype(cxt->cputypes[i]);
+ free(cxt->idx2cpunum);
+ free(cxt->present);
+ free(cxt->online);
+ if (cxt->arch)
+ free(cxt->arch->name);
+ free(cxt->arch);
free(cxt->cputypes);
free(cxt->cpus);
free(cxt);
lscpu_read_cpuinfo(cxt);
lscpu_read_architecture(cxt);
+ lscpu_read_cpulists(cxt);
lscpu_free_context(cxt);
return EXIT_SUCCESS;