1 #ifndef _GNU_SOURCE 2 #define _GNU_SOURCE 3 #endif 4 5 #include <stdio.h> 6 #include <unistd.h> 7 #include <errno.h> 8 #include <sched.h> 9 #include <sys/stat.h> 10 #include <sys/syscall.h> 11 #include <assert.h> 12 #ifndef DISABLE_NUMA 13 #include <numa.h> 14 #endif 15 16 #define MAX_FILE_NAME 1024 17 18 /*----------------------------------------------------------------------------*/ 19 int 20 GetNumCPUs() 21 { 22 return sysconf(_SC_NPROCESSORS_ONLN); 23 } 24 /*----------------------------------------------------------------------------*/ 25 pid_t 26 Gettid() 27 { 28 return syscall(__NR_gettid); 29 } 30 /*----------------------------------------------------------------------------*/ 31 int 32 mtcp_core_affinitize(int cpu) 33 { 34 #ifndef DISABLE_NUMA 35 struct bitmask *bmask; 36 #endif /* DISABLE_NUMA */ 37 cpu_set_t cpus; 38 FILE *fp; 39 char sysfname[MAX_FILE_NAME]; 40 int phy_id; 41 size_t n; 42 int ret; 43 44 n = GetNumCPUs(); 45 46 if (cpu < 0 || cpu >= (int) n) { 47 errno = -EINVAL; 48 return -1; 49 } 50 51 CPU_ZERO(&cpus); 52 CPU_SET((unsigned)cpu, &cpus); 53 54 ret = sched_setaffinity(Gettid(), sizeof(cpus), &cpus); 55 56 #ifndef DISABLE_NUMA 57 if (numa_max_node() == 0) 58 return ret; 59 60 bmask = numa_bitmask_alloc(numa_max_node() + 1); 61 assert(bmask); 62 #endif /* DISABLE_NUMA */ 63 64 /* read physical id of the core from sys information */ 65 snprintf(sysfname, MAX_FILE_NAME - 1, 66 "/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpu); 67 fp = fopen(sysfname, "r"); 68 if (!fp) { 69 perror(sysfname); 70 errno = EFAULT; 71 return -1; 72 } 73 74 ret = fscanf(fp, "%d", &phy_id); 75 if (ret != 1) { 76 fclose(fp); 77 perror("Fail to read core id"); 78 errno = EFAULT; 79 return -1; 80 } 81 82 83 #ifndef DISABLE_NUMA 84 numa_bitmask_setbit(bmask, phy_id); 85 numa_set_membind(bmask); 86 numa_bitmask_free(bmask); 87 #endif /* DISABLE_NUMA */ 88 89 fclose(fp); 90 91 return ret; 92 } 93