1f08c3bdfSopenharmony_ci#include "config.h" 2f08c3bdfSopenharmony_ci#include <stdio.h> 3f08c3bdfSopenharmony_ci#include <stdlib.h> 4f08c3bdfSopenharmony_ci#include <string.h> 5f08c3bdfSopenharmony_ci#include <sys/types.h> 6f08c3bdfSopenharmony_ci#include <dirent.h> 7f08c3bdfSopenharmony_ci#include <err.h> 8f08c3bdfSopenharmony_ci#include <errno.h> 9f08c3bdfSopenharmony_ci 10f08c3bdfSopenharmony_ci#include "bitmask.h" 11f08c3bdfSopenharmony_ci#include "cpuset.h" 12f08c3bdfSopenharmony_ci#include "common.h" 13f08c3bdfSopenharmony_ci#include "cpuinfo.h" 14f08c3bdfSopenharmony_ci 15f08c3bdfSopenharmony_ci#if HAVE_LINUX_MEMPOLICY_H 16f08c3bdfSopenharmony_ci 17f08c3bdfSopenharmony_ci#define CPUINFO_FILE "/proc/cpuinfo" 18f08c3bdfSopenharmony_ci#define SCHEDSTAT_FILE "/proc/schedstat" 19f08c3bdfSopenharmony_ci#define CGROUPINFO_FILE "/proc/cgroups" 20f08c3bdfSopenharmony_ci#define SYS_CPU_DIR "/sys/devices/system/cpu" 21f08c3bdfSopenharmony_ci#define LIST_PRESENT_CPU_FILE "/sys/devices/system/cpu/present" 22f08c3bdfSopenharmony_ci#define LIST_ONLINE_CPU_FILE "/sys/devices/system/cpu/online" 23f08c3bdfSopenharmony_ci 24f08c3bdfSopenharmony_cistruct cpuinfo *cpus; 25f08c3bdfSopenharmony_ciint ncpus; 26f08c3bdfSopenharmony_ciint cpus_nbits; 27f08c3bdfSopenharmony_ci 28f08c3bdfSopenharmony_ci/* get cpu_baseinfo from /proc/cpuinfo */ 29f08c3bdfSopenharmony_cistatic int get_cpu_baseinfo(void) 30f08c3bdfSopenharmony_ci{ 31f08c3bdfSopenharmony_ci FILE *fp = NULL; 32f08c3bdfSopenharmony_ci char buf[BUFFSIZE]; 33f08c3bdfSopenharmony_ci char *istr = NULL, *valstr = NULL, *saveptr = NULL; 34f08c3bdfSopenharmony_ci int ci = 0; 35f08c3bdfSopenharmony_ci int data = 0; 36f08c3bdfSopenharmony_ci 37f08c3bdfSopenharmony_ci /* get the number of cpus including offline cpus */ 38f08c3bdfSopenharmony_ci if (!ncpus) { 39f08c3bdfSopenharmony_ci ncpus = get_ncpus(); 40f08c3bdfSopenharmony_ci if (ncpus <= 0) 41f08c3bdfSopenharmony_ci return -1; 42f08c3bdfSopenharmony_ci } 43f08c3bdfSopenharmony_ci 44f08c3bdfSopenharmony_ci if (cpus != NULL) { 45f08c3bdfSopenharmony_ci free(cpus); 46f08c3bdfSopenharmony_ci cpus = NULL; 47f08c3bdfSopenharmony_ci } 48f08c3bdfSopenharmony_ci 49f08c3bdfSopenharmony_ci /* allocate the memory space for cpus */ 50f08c3bdfSopenharmony_ci cpus = malloc(sizeof(*cpus) * ncpus); 51f08c3bdfSopenharmony_ci if (cpus == NULL) 52f08c3bdfSopenharmony_ci return -1; 53f08c3bdfSopenharmony_ci memset(cpus, 0, sizeof(*cpus) * ncpus); 54f08c3bdfSopenharmony_ci 55f08c3bdfSopenharmony_ci /* open file /proc/cpuinfo */ 56f08c3bdfSopenharmony_ci if ((fp = fopen(CPUINFO_FILE, "r")) == NULL) 57f08c3bdfSopenharmony_ci return -1; 58f08c3bdfSopenharmony_ci 59f08c3bdfSopenharmony_ci /* get cpuinfo */ 60f08c3bdfSopenharmony_ci while (fgets(buf, sizeof(buf), fp) != NULL) { 61f08c3bdfSopenharmony_ci istr = strtok_r(buf, "\t", &saveptr); 62f08c3bdfSopenharmony_ci valstr = strchr(saveptr, ':'); 63f08c3bdfSopenharmony_ci if (valstr == NULL) 64f08c3bdfSopenharmony_ci continue; 65f08c3bdfSopenharmony_ci valstr++; 66f08c3bdfSopenharmony_ci sscanf(valstr, " %d\n", &data); 67f08c3bdfSopenharmony_ci if (!strcmp(istr, "processor")) { 68f08c3bdfSopenharmony_ci if (data >= ncpus) { 69f08c3bdfSopenharmony_ci warnx("Warn: wrong cpu index"); 70f08c3bdfSopenharmony_ci fclose(fp); 71f08c3bdfSopenharmony_ci return -1; 72f08c3bdfSopenharmony_ci } 73f08c3bdfSopenharmony_ci ci = data; 74f08c3bdfSopenharmony_ci cpus[ci].online = 1; 75f08c3bdfSopenharmony_ci } 76f08c3bdfSopenharmony_ci } 77f08c3bdfSopenharmony_ci 78f08c3bdfSopenharmony_ci fclose(fp); 79f08c3bdfSopenharmony_ci return 0; 80f08c3bdfSopenharmony_ci} 81f08c3bdfSopenharmony_ci 82f08c3bdfSopenharmony_ci/* 83f08c3bdfSopenharmony_ci * get the cpu bitmask of the online processors 84f08c3bdfSopenharmony_ci * 85f08c3bdfSopenharmony_ci * return value: 0 - success 86f08c3bdfSopenharmony_ci * -1 - failed 87f08c3bdfSopenharmony_ci */ 88f08c3bdfSopenharmony_ciint online_cpumask(struct bitmask *cpumask) 89f08c3bdfSopenharmony_ci{ 90f08c3bdfSopenharmony_ci FILE *fp = NULL; 91f08c3bdfSopenharmony_ci char buf[BUFFSIZE]; 92f08c3bdfSopenharmony_ci int i; 93f08c3bdfSopenharmony_ci 94f08c3bdfSopenharmony_ci if (cpumask == NULL) 95f08c3bdfSopenharmony_ci return -1; 96f08c3bdfSopenharmony_ci /* 97f08c3bdfSopenharmony_ci * open file /sys/devices/system/cpu/online and get online 98f08c3bdfSopenharmony_ci * cpulist. 99f08c3bdfSopenharmony_ci */ 100f08c3bdfSopenharmony_ci if ((fp = fopen(LIST_ONLINE_CPU_FILE, "r")) == NULL) { 101f08c3bdfSopenharmony_ci if (get_cpu_baseinfo() != 0) 102f08c3bdfSopenharmony_ci return -1; 103f08c3bdfSopenharmony_ci for (i = 0; i < ncpus; i++) { 104f08c3bdfSopenharmony_ci if (cpus[i].online) 105f08c3bdfSopenharmony_ci bitmask_setbit(cpumask, i); 106f08c3bdfSopenharmony_ci } 107f08c3bdfSopenharmony_ci } else { 108f08c3bdfSopenharmony_ci if (fgets(buf, sizeof(buf), fp) == NULL) { 109f08c3bdfSopenharmony_ci fclose(fp); 110f08c3bdfSopenharmony_ci return -1; 111f08c3bdfSopenharmony_ci } 112f08c3bdfSopenharmony_ci fclose(fp); 113f08c3bdfSopenharmony_ci 114f08c3bdfSopenharmony_ci /* parse present cpu list to bitmap */ 115f08c3bdfSopenharmony_ci buf[strlen(buf) - 1] = '\0'; 116f08c3bdfSopenharmony_ci if (bitmask_parselist(buf, cpumask) != 0) 117f08c3bdfSopenharmony_ci return -1; 118f08c3bdfSopenharmony_ci } 119f08c3bdfSopenharmony_ci 120f08c3bdfSopenharmony_ci return 0; 121f08c3bdfSopenharmony_ci} 122f08c3bdfSopenharmony_ci 123f08c3bdfSopenharmony_ci/* 124f08c3bdfSopenharmony_ci * get the cpu bitmask of the present processors including offline CPUs 125f08c3bdfSopenharmony_ci * 126f08c3bdfSopenharmony_ci * return value: 0 - success 127f08c3bdfSopenharmony_ci * -1 - failed 128f08c3bdfSopenharmony_ci */ 129f08c3bdfSopenharmony_ciint present_cpumask(struct bitmask *cpumask) 130f08c3bdfSopenharmony_ci{ 131f08c3bdfSopenharmony_ci FILE *fp = NULL; 132f08c3bdfSopenharmony_ci char buf[BUFFSIZE]; 133f08c3bdfSopenharmony_ci char c_relpath[PATH_MAX]; 134f08c3bdfSopenharmony_ci int cpu = -1; 135f08c3bdfSopenharmony_ci 136f08c3bdfSopenharmony_ci if (cpumask == NULL) 137f08c3bdfSopenharmony_ci return -1; 138f08c3bdfSopenharmony_ci /* 139f08c3bdfSopenharmony_ci * open file /sys/devices/system/cpu/present and get present 140f08c3bdfSopenharmony_ci * cpulist. 141f08c3bdfSopenharmony_ci */ 142f08c3bdfSopenharmony_ci if ((fp = fopen(LIST_PRESENT_CPU_FILE, "r")) == NULL) { 143f08c3bdfSopenharmony_ci while_each_childdir(SYS_CPU_DIR, "/", c_relpath, 144f08c3bdfSopenharmony_ci sizeof(c_relpath)) { 145f08c3bdfSopenharmony_ci if (!strncmp(c_relpath + 1, "cpu", 3) 146f08c3bdfSopenharmony_ci && sscanf(c_relpath + 4, "%d", &cpu) > 0) { 147f08c3bdfSopenharmony_ci if (cpu >= 0) 148f08c3bdfSopenharmony_ci bitmask_setbit(cpumask, cpu); 149f08c3bdfSopenharmony_ci } 150f08c3bdfSopenharmony_ci } 151f08c3bdfSopenharmony_ci end_while_each_childdir} else { 152f08c3bdfSopenharmony_ci if (fgets(buf, sizeof(buf), fp) == NULL) { 153f08c3bdfSopenharmony_ci fclose(fp); 154f08c3bdfSopenharmony_ci return -1; 155f08c3bdfSopenharmony_ci } 156f08c3bdfSopenharmony_ci fclose(fp); 157f08c3bdfSopenharmony_ci 158f08c3bdfSopenharmony_ci /* parse present cpu list to bitmap */ 159f08c3bdfSopenharmony_ci buf[strlen(buf) - 1] = '\0'; 160f08c3bdfSopenharmony_ci if (bitmask_parselist(buf, cpumask) != 0) 161f08c3bdfSopenharmony_ci return -1; 162f08c3bdfSopenharmony_ci } 163f08c3bdfSopenharmony_ci 164f08c3bdfSopenharmony_ci return 0; 165f08c3bdfSopenharmony_ci} 166f08c3bdfSopenharmony_ci 167f08c3bdfSopenharmony_ci/* 168f08c3bdfSopenharmony_ci * get the number of the processors including offline CPUs 169f08c3bdfSopenharmony_ci * We get this number from /sys/devices/system/cpu/present. 170f08c3bdfSopenharmony_ci * By analyzing the present cpu list, we get the number of all cpus 171f08c3bdfSopenharmony_ci */ 172f08c3bdfSopenharmony_ciint get_ncpus(void) 173f08c3bdfSopenharmony_ci{ 174f08c3bdfSopenharmony_ci struct bitmask *bmp = NULL; 175f08c3bdfSopenharmony_ci int n = 0; 176f08c3bdfSopenharmony_ci 177f08c3bdfSopenharmony_ci /* get the bitmask's len */ 178f08c3bdfSopenharmony_ci cpus_nbits = cpuset_cpus_nbits(); 179f08c3bdfSopenharmony_ci if (cpus_nbits <= 0) 180f08c3bdfSopenharmony_ci return -1; 181f08c3bdfSopenharmony_ci 182f08c3bdfSopenharmony_ci /* allocate the space for bitmask */ 183f08c3bdfSopenharmony_ci bmp = bitmask_alloc(cpus_nbits); 184f08c3bdfSopenharmony_ci if (bmp == NULL) 185f08c3bdfSopenharmony_ci return -1; 186f08c3bdfSopenharmony_ci 187f08c3bdfSopenharmony_ci if (present_cpumask(bmp)) { 188f08c3bdfSopenharmony_ci bitmask_free(bmp); 189f08c3bdfSopenharmony_ci return -1; 190f08c3bdfSopenharmony_ci } 191f08c3bdfSopenharmony_ci 192f08c3bdfSopenharmony_ci /* Number of highest set bit +1 is the number of the CPUs */ 193f08c3bdfSopenharmony_ci n = bitmask_last(bmp) + 1; 194f08c3bdfSopenharmony_ci bitmask_free(bmp); 195f08c3bdfSopenharmony_ci 196f08c3bdfSopenharmony_ci return n; 197f08c3bdfSopenharmony_ci} 198f08c3bdfSopenharmony_ci 199f08c3bdfSopenharmony_ci/* get the sched domain's info for each cpu */ 200f08c3bdfSopenharmony_cistatic int get_sched_domains(void) 201f08c3bdfSopenharmony_ci{ 202f08c3bdfSopenharmony_ci FILE *fp = NULL; 203f08c3bdfSopenharmony_ci char buf[BUFFSIZE]; 204f08c3bdfSopenharmony_ci char str1[20], str2[BUFFSIZE]; 205f08c3bdfSopenharmony_ci int ci = 0; 206f08c3bdfSopenharmony_ci 207f08c3bdfSopenharmony_ci /* get the bitmask's len */ 208f08c3bdfSopenharmony_ci if (!cpus_nbits) { 209f08c3bdfSopenharmony_ci cpus_nbits = cpuset_cpus_nbits(); 210f08c3bdfSopenharmony_ci if (cpus_nbits <= 0) { 211f08c3bdfSopenharmony_ci warnx("get cpus nbits failed."); 212f08c3bdfSopenharmony_ci return -1; 213f08c3bdfSopenharmony_ci } 214f08c3bdfSopenharmony_ci } 215f08c3bdfSopenharmony_ci 216f08c3bdfSopenharmony_ci /* open file /proc/schedstat */ 217f08c3bdfSopenharmony_ci if ((fp = fopen(SCHEDSTAT_FILE, "r")) == NULL) 218f08c3bdfSopenharmony_ci return -1; 219f08c3bdfSopenharmony_ci 220f08c3bdfSopenharmony_ci /* get cpuinfo */ 221f08c3bdfSopenharmony_ci while (fgets(buf, sizeof(buf), fp) != NULL) { 222f08c3bdfSopenharmony_ci sscanf(buf, "%s %s", str1, str2); 223f08c3bdfSopenharmony_ci if (!strncmp(str1, "cpu", 3)) { 224f08c3bdfSopenharmony_ci ci = atoi(str1 + 3); 225f08c3bdfSopenharmony_ci if (ci < 0 || ci >= ncpus) { 226f08c3bdfSopenharmony_ci fprintf(stderr, "Warn: wrong cpu index"); 227f08c3bdfSopenharmony_ci fclose(fp); 228f08c3bdfSopenharmony_ci return -1; 229f08c3bdfSopenharmony_ci } 230f08c3bdfSopenharmony_ci } else if (!strncmp(str1, "domain", 6)) { 231f08c3bdfSopenharmony_ci if (!cpus[ci].sched_domain) { 232f08c3bdfSopenharmony_ci cpus[ci].sched_domain = 233f08c3bdfSopenharmony_ci bitmask_alloc(cpus_nbits); 234f08c3bdfSopenharmony_ci if (!cpus[ci].sched_domain) { 235f08c3bdfSopenharmony_ci fclose(fp); 236f08c3bdfSopenharmony_ci return -1; 237f08c3bdfSopenharmony_ci } 238f08c3bdfSopenharmony_ci } 239f08c3bdfSopenharmony_ci if (bitmask_parsehex(str2, cpus[ci].sched_domain)) { 240f08c3bdfSopenharmony_ci fclose(fp); 241f08c3bdfSopenharmony_ci return -1; 242f08c3bdfSopenharmony_ci } 243f08c3bdfSopenharmony_ci } 244f08c3bdfSopenharmony_ci } 245f08c3bdfSopenharmony_ci 246f08c3bdfSopenharmony_ci fclose(fp); 247f08c3bdfSopenharmony_ci return 0; 248f08c3bdfSopenharmony_ci} 249f08c3bdfSopenharmony_ci 250f08c3bdfSopenharmony_ciint getcpuinfo(void) 251f08c3bdfSopenharmony_ci{ 252f08c3bdfSopenharmony_ci int i; 253f08c3bdfSopenharmony_ci int node = -1; 254f08c3bdfSopenharmony_ci 255f08c3bdfSopenharmony_ci /* get the number of cpus including offline cpus */ 256f08c3bdfSopenharmony_ci if (!ncpus) { 257f08c3bdfSopenharmony_ci ncpus = get_ncpus(); 258f08c3bdfSopenharmony_ci if (ncpus <= 0) 259f08c3bdfSopenharmony_ci return -1; 260f08c3bdfSopenharmony_ci } 261f08c3bdfSopenharmony_ci 262f08c3bdfSopenharmony_ci if (cpus == NULL) { 263f08c3bdfSopenharmony_ci if (get_cpu_baseinfo() != 0) { 264f08c3bdfSopenharmony_ci warn("get base infomation of cpus from /proc/cpuinfo " 265f08c3bdfSopenharmony_ci "failed."); 266f08c3bdfSopenharmony_ci return -1; 267f08c3bdfSopenharmony_ci } 268f08c3bdfSopenharmony_ci } 269f08c3bdfSopenharmony_ci 270f08c3bdfSopenharmony_ci /* which node is every cpu belong to? */ 271f08c3bdfSopenharmony_ci for (i = 0; i < ncpus; i++) { 272f08c3bdfSopenharmony_ci node = cpuset_cpu2node(i); 273f08c3bdfSopenharmony_ci if (node == -1) 274f08c3bdfSopenharmony_ci warnx("cpu2node failed(cpu = %d)", i); 275f08c3bdfSopenharmony_ci cpus[i].nodeid = node; 276f08c3bdfSopenharmony_ci } 277f08c3bdfSopenharmony_ci 278f08c3bdfSopenharmony_ci /* get sched domain's infomation for each cpu */ 279f08c3bdfSopenharmony_ci if (get_sched_domains()) { 280f08c3bdfSopenharmony_ci warnx("get sched domain's info for each cpu failed."); 281f08c3bdfSopenharmony_ci return -1; 282f08c3bdfSopenharmony_ci } 283f08c3bdfSopenharmony_ci 284f08c3bdfSopenharmony_ci return 0; 285f08c3bdfSopenharmony_ci} 286f08c3bdfSopenharmony_ci 287f08c3bdfSopenharmony_ci/* get the number of the cpuset groups */ 288f08c3bdfSopenharmony_cistatic int get_num_cpusets(void) 289f08c3bdfSopenharmony_ci{ 290f08c3bdfSopenharmony_ci FILE *fp = NULL; 291f08c3bdfSopenharmony_ci char buf[BUFFSIZE]; 292f08c3bdfSopenharmony_ci char subsys_name[BUFFSIZE]; 293f08c3bdfSopenharmony_ci int num_cgroups = 0; 294f08c3bdfSopenharmony_ci int hierarchy; 295f08c3bdfSopenharmony_ci int enabled; 296f08c3bdfSopenharmony_ci 297f08c3bdfSopenharmony_ci /* open file /proc/cgroups and get num cpusets */ 298f08c3bdfSopenharmony_ci if ((fp = fopen(CGROUPINFO_FILE, "r")) == NULL) 299f08c3bdfSopenharmony_ci return -1; 300f08c3bdfSopenharmony_ci 301f08c3bdfSopenharmony_ci while (fgets(buf, sizeof(buf), fp) != NULL) { 302f08c3bdfSopenharmony_ci if (!strncmp(buf, "cpuset", 6)) { 303f08c3bdfSopenharmony_ci sscanf(buf, "%s\t%d\t%d\t%d\n", subsys_name, 304f08c3bdfSopenharmony_ci &hierarchy, &num_cgroups, &enabled); 305f08c3bdfSopenharmony_ci } 306f08c3bdfSopenharmony_ci } 307f08c3bdfSopenharmony_ci 308f08c3bdfSopenharmony_ci fclose(fp); 309f08c3bdfSopenharmony_ci 310f08c3bdfSopenharmony_ci return num_cgroups; 311f08c3bdfSopenharmony_ci} 312f08c3bdfSopenharmony_ci 313f08c3bdfSopenharmony_cistatic struct cpuset **cpusets; 314f08c3bdfSopenharmony_cistatic int ncpusets; 315f08c3bdfSopenharmony_ci 316f08c3bdfSopenharmony_cistatic int find_domain_cpusets(char *relpath) 317f08c3bdfSopenharmony_ci{ 318f08c3bdfSopenharmony_ci struct cpuset *cp = NULL; 319f08c3bdfSopenharmony_ci char c_relpath[PATH_MAX]; 320f08c3bdfSopenharmony_ci int ret = 0; 321f08c3bdfSopenharmony_ci 322f08c3bdfSopenharmony_ci if (relpath == NULL) { 323f08c3bdfSopenharmony_ci errno = -EFAULT; 324f08c3bdfSopenharmony_ci return -1; 325f08c3bdfSopenharmony_ci } 326f08c3bdfSopenharmony_ci 327f08c3bdfSopenharmony_ci cp = cpuset_alloc(); 328f08c3bdfSopenharmony_ci if (cp == NULL) { 329f08c3bdfSopenharmony_ci errno = -ENOMEM; 330f08c3bdfSopenharmony_ci return -1; 331f08c3bdfSopenharmony_ci } 332f08c3bdfSopenharmony_ci 333f08c3bdfSopenharmony_ci if (cpuset_query(cp, relpath)) { 334f08c3bdfSopenharmony_ci cpuset_free(cp); 335f08c3bdfSopenharmony_ci return -1; 336f08c3bdfSopenharmony_ci } 337f08c3bdfSopenharmony_ci 338f08c3bdfSopenharmony_ci if (cpuset_cpus_weight(cp) == 0) 339f08c3bdfSopenharmony_ci return 0; 340f08c3bdfSopenharmony_ci 341f08c3bdfSopenharmony_ci if (cpuset_cpus_weight(cp) > 0 342f08c3bdfSopenharmony_ci && cpuset_get_iopt(cp, "sched_load_balance") == 1) { 343f08c3bdfSopenharmony_ci cpusets[ncpusets] = cp; 344f08c3bdfSopenharmony_ci ncpusets++; 345f08c3bdfSopenharmony_ci return 0; 346f08c3bdfSopenharmony_ci } 347f08c3bdfSopenharmony_ci 348f08c3bdfSopenharmony_ci while_each_childdir(cpuset_mountpoint(), relpath, c_relpath, 349f08c3bdfSopenharmony_ci sizeof(c_relpath)) { 350f08c3bdfSopenharmony_ci if ((ret = find_domain_cpusets(c_relpath))) 351f08c3bdfSopenharmony_ci break; 352f08c3bdfSopenharmony_ci } 353f08c3bdfSopenharmony_ci end_while_each_childdir; 354f08c3bdfSopenharmony_ci 355f08c3bdfSopenharmony_ci return ret; 356f08c3bdfSopenharmony_ci} 357f08c3bdfSopenharmony_ci 358f08c3bdfSopenharmony_cistruct bitmask **domains; 359f08c3bdfSopenharmony_ciint ndomains; 360f08c3bdfSopenharmony_ci 361f08c3bdfSopenharmony_ciint partition_domains(void) 362f08c3bdfSopenharmony_ci{ 363f08c3bdfSopenharmony_ci int num_cpusets = 0; 364f08c3bdfSopenharmony_ci int i, j; 365f08c3bdfSopenharmony_ci struct bitmask *cpusa = NULL, *cpusb = NULL, *cpusc = NULL; 366f08c3bdfSopenharmony_ci int *flg = NULL; 367f08c3bdfSopenharmony_ci int ret = 0; 368f08c3bdfSopenharmony_ci 369f08c3bdfSopenharmony_ci num_cpusets = get_num_cpusets(); 370f08c3bdfSopenharmony_ci if (num_cpusets == 0) { 371f08c3bdfSopenharmony_ci warnx("cpuset subsystem is't compiled into kernel."); 372f08c3bdfSopenharmony_ci return -1; 373f08c3bdfSopenharmony_ci } 374f08c3bdfSopenharmony_ci 375f08c3bdfSopenharmony_ci if (!cpus_nbits) { 376f08c3bdfSopenharmony_ci cpus_nbits = cpuset_cpus_nbits(); 377f08c3bdfSopenharmony_ci if (!cpus_nbits) { 378f08c3bdfSopenharmony_ci warnx("nbits of cpus is wrong."); 379f08c3bdfSopenharmony_ci return -1; 380f08c3bdfSopenharmony_ci } 381f08c3bdfSopenharmony_ci } 382f08c3bdfSopenharmony_ci 383f08c3bdfSopenharmony_ci cpusa = bitmask_alloc(cpus_nbits); 384f08c3bdfSopenharmony_ci if (cpusa == NULL) { 385f08c3bdfSopenharmony_ci warnx("bitmask_alloc for partition domains failed."); 386f08c3bdfSopenharmony_ci return -1; 387f08c3bdfSopenharmony_ci } 388f08c3bdfSopenharmony_ci 389f08c3bdfSopenharmony_ci cpusb = bitmask_alloc(cpus_nbits); 390f08c3bdfSopenharmony_ci if (cpusb == NULL) { 391f08c3bdfSopenharmony_ci warnx("bitmask_alloc for partition domains failed."); 392f08c3bdfSopenharmony_ci ret = -1; 393f08c3bdfSopenharmony_ci goto errcpusb; 394f08c3bdfSopenharmony_ci } 395f08c3bdfSopenharmony_ci 396f08c3bdfSopenharmony_ci cpusc = bitmask_alloc(cpus_nbits); 397f08c3bdfSopenharmony_ci if (cpusb == NULL) { 398f08c3bdfSopenharmony_ci warnx("bitmask_alloc for partition domains failed."); 399f08c3bdfSopenharmony_ci ret = -1; 400f08c3bdfSopenharmony_ci goto errcpusc; 401f08c3bdfSopenharmony_ci } 402f08c3bdfSopenharmony_ci 403f08c3bdfSopenharmony_ci cpusets = malloc(num_cpusets * sizeof(*cpusets)); 404f08c3bdfSopenharmony_ci if (cpusets == NULL) { 405f08c3bdfSopenharmony_ci warnx("alloc cpusets space failed."); 406f08c3bdfSopenharmony_ci ret = -1; 407f08c3bdfSopenharmony_ci goto errcpusets; 408f08c3bdfSopenharmony_ci } 409f08c3bdfSopenharmony_ci 410f08c3bdfSopenharmony_ci if ((ret = find_domain_cpusets("/"))) { 411f08c3bdfSopenharmony_ci warnx("find domain cpusets failed."); 412f08c3bdfSopenharmony_ci goto errfindcpusets; 413f08c3bdfSopenharmony_ci } 414f08c3bdfSopenharmony_ci 415f08c3bdfSopenharmony_ci flg = malloc(num_cpusets * sizeof(int)); 416f08c3bdfSopenharmony_ci if (flg == NULL) { 417f08c3bdfSopenharmony_ci warnx("alloc flg failed."); 418f08c3bdfSopenharmony_ci ret = -1; 419f08c3bdfSopenharmony_ci goto errfindcpusets; 420f08c3bdfSopenharmony_ci } 421f08c3bdfSopenharmony_ci memset(flg, 0, num_cpusets * sizeof(int)); 422f08c3bdfSopenharmony_ci 423f08c3bdfSopenharmony_ci ndomains = ncpusets; 424f08c3bdfSopenharmony_cirestart: 425f08c3bdfSopenharmony_ci for (i = 0; i < ncpusets; i++) { 426f08c3bdfSopenharmony_ci struct cpuset *cpa = cpusets[i]; 427f08c3bdfSopenharmony_ci 428f08c3bdfSopenharmony_ci if (flg[i]) 429f08c3bdfSopenharmony_ci continue; 430f08c3bdfSopenharmony_ci 431f08c3bdfSopenharmony_ci cpuset_getcpus(cpa, cpusa); 432f08c3bdfSopenharmony_ci 433f08c3bdfSopenharmony_ci for (j = i + 1; j < ncpusets; j++) { 434f08c3bdfSopenharmony_ci struct cpuset *cpb = cpusets[j]; 435f08c3bdfSopenharmony_ci 436f08c3bdfSopenharmony_ci if (flg[j]) 437f08c3bdfSopenharmony_ci continue; 438f08c3bdfSopenharmony_ci 439f08c3bdfSopenharmony_ci cpuset_getcpus(cpb, cpusb); 440f08c3bdfSopenharmony_ci if (bitmask_intersects(cpusa, cpusb)) { 441f08c3bdfSopenharmony_ci bitmask_or(cpusc, cpusa, cpusb); 442f08c3bdfSopenharmony_ci cpuset_setcpus(cpa, cpusc); 443f08c3bdfSopenharmony_ci flg[j] = 1; 444f08c3bdfSopenharmony_ci ndomains--; 445f08c3bdfSopenharmony_ci goto restart; 446f08c3bdfSopenharmony_ci } 447f08c3bdfSopenharmony_ci } 448f08c3bdfSopenharmony_ci } 449f08c3bdfSopenharmony_ci 450f08c3bdfSopenharmony_ci domains = malloc(ndomains * sizeof(*domains)); 451f08c3bdfSopenharmony_ci if (domains == NULL) { 452f08c3bdfSopenharmony_ci warnx("alloc domains space failed."); 453f08c3bdfSopenharmony_ci ret = -1; 454f08c3bdfSopenharmony_ci goto errdomains; 455f08c3bdfSopenharmony_ci } 456f08c3bdfSopenharmony_ci 457f08c3bdfSopenharmony_ci for (i = 0, j = 0; i < ncpusets; i++) { 458f08c3bdfSopenharmony_ci if (flg[i]) 459f08c3bdfSopenharmony_ci continue; 460f08c3bdfSopenharmony_ci domains[j] = bitmask_alloc(cpus_nbits); 461f08c3bdfSopenharmony_ci if (cpuset_getcpus(cpusets[i], domains[j])) { 462f08c3bdfSopenharmony_ci warnx("cpuset getcpus failed."); 463f08c3bdfSopenharmony_ci ret = -1; 464f08c3bdfSopenharmony_ci goto errgetdomains; 465f08c3bdfSopenharmony_ci } 466f08c3bdfSopenharmony_ci j++; 467f08c3bdfSopenharmony_ci } 468f08c3bdfSopenharmony_ci goto errdomains; 469f08c3bdfSopenharmony_ci 470f08c3bdfSopenharmony_cierrgetdomains: 471f08c3bdfSopenharmony_ci for (i = 0; i < j; i++) 472f08c3bdfSopenharmony_ci bitmask_free(domains[i]); 473f08c3bdfSopenharmony_ci free(domains); 474f08c3bdfSopenharmony_ci domains = NULL; 475f08c3bdfSopenharmony_cierrdomains: 476f08c3bdfSopenharmony_ci free(flg); 477f08c3bdfSopenharmony_cierrfindcpusets: 478f08c3bdfSopenharmony_ci for (i = 0; i < ncpusets; i++) 479f08c3bdfSopenharmony_ci cpuset_free(cpusets[i]); 480f08c3bdfSopenharmony_ci free(cpusets); 481f08c3bdfSopenharmony_ci cpusets = NULL; 482f08c3bdfSopenharmony_ci ncpusets = 0; 483f08c3bdfSopenharmony_cierrcpusets: 484f08c3bdfSopenharmony_ci bitmask_free(cpusc); 485f08c3bdfSopenharmony_cierrcpusc: 486f08c3bdfSopenharmony_ci bitmask_free(cpusb); 487f08c3bdfSopenharmony_cierrcpusb: 488f08c3bdfSopenharmony_ci bitmask_free(cpusa); 489f08c3bdfSopenharmony_ci return ret; 490f08c3bdfSopenharmony_ci} 491f08c3bdfSopenharmony_ci 492f08c3bdfSopenharmony_ci#endif 493