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
GetNumCPUs()20 GetNumCPUs()
21 {
22 return sysconf(_SC_NPROCESSORS_ONLN);
23 }
24 /*----------------------------------------------------------------------------*/
25 pid_t
Gettid()26 Gettid()
27 {
28 return syscall(__NR_gettid);
29 }
30 /*----------------------------------------------------------------------------*/
31 int
mtcp_core_affinitize(int cpu)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