+static cpu_set_t *get_online_cpus(void)
+{
+ FILE *cpus;
+ cpu_set_t *set;
+ size_t alloc_size;
+ int cpuid, prevcpuid = -1;
+ char nextch;
+ int n, ncpu, curcpu = 0;
+ int *cpu_nums;
+
+ ncpu = sysconf(_SC_NPROCESSORS_CONF);
+ if (ncpu < 0)
+ return NULL;
+
+ cpu_nums = malloc(sizeof(int)*ncpu);
+ if (!cpu_nums) {
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ /*
+ * There is no way to easily get maximum CPU number. So we have to
+ * parse the file first to find it out and then create appropriate
+ * cpuset
+ */
+ cpus = my_fopen("/sys/devices/system/cpu/online", "r");
+ for (;;) {
+ n = fscanf(cpus, "%d%c", &cpuid, &nextch);
+ if (n <= 0)
+ break;
+ if (n == 2 && nextch == '-') {
+ prevcpuid = cpuid;
+ continue;
+ }
+ if (prevcpuid == -1)
+ prevcpuid = cpuid;
+ while (prevcpuid <= cpuid) {
+ /* More CPUs listed than configured? */
+ if (curcpu >= ncpu) {
+ errno = EINVAL;
+ return NULL;
+ }
+ cpu_nums[curcpu++] = prevcpuid++;
+ }
+ prevcpuid = -1;
+ }
+ fclose(cpus);
+
+ ncpu = curcpu;
+ max_cpus = cpu_nums[ncpu - 1] + 1;
+
+ /* Now that we have maximum cpu number, create a cpuset */
+ set = CPU_ALLOC(max_cpus);
+ if (!set) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ alloc_size = CPU_ALLOC_SIZE(max_cpus);
+ CPU_ZERO_S(alloc_size, set);
+
+ for (curcpu = 0; curcpu < ncpu; curcpu++)
+ CPU_SET_S(cpu_nums[curcpu], alloc_size, set);
+
+ free(cpu_nums);
+
+ return set;
+}
+