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