Skip to content

Commit 3b24bef

Browse files
committed
Respect shadow's initial CPU affinity
Progress on #1565 Fixes #1576
1 parent aa01a2c commit 3b24bef

1 file changed

Lines changed: 35 additions & 3 deletions

File tree

src/main/host/affinity.c

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#endif // _GNU_SOURCE
66

77
#include <assert.h>
8+
#include <errno.h>
89
#include <pthread.h>
910
#include <sched.h>
1011
#include <stdbool.h>
@@ -36,6 +37,7 @@ typedef struct _CPUInfo {
3637
} CPUInfo;
3738

3839
typedef struct _PlatformCPUInfo {
40+
cpu_set_t* initial_affinity;
3941
CPUInfo* p_cpus;
4042
size_t n_cpus;
4143
int max_cpu_num;
@@ -126,6 +128,12 @@ static int _cpuinfo_compare(const CPUInfo* lhs, const CPUInfo* rhs) {
126128
(lhs->logical_cpu_num < rhs->logical_cpu_num);
127129
}
128130

131+
static bool _cpuIdxIsEligible(size_t idx) {
132+
assert(idx < _global_platform_info.n_cpus);
133+
return CPU_ISSET_S(_global_platform_info.p_cpus[idx].logical_cpu_num,
134+
_global_platform_info.n_cpus, _global_platform_info.initial_affinity);
135+
}
136+
129137
/*
130138
* rwails: I tried using a priority queue here first, but since the priorities
131139
* change dynamically with each allocation, it doesn't work with out-of-the-box
@@ -136,11 +144,22 @@ const CPUInfo* _get_best_cpu() {
136144

137145
assert(_global_platform_info.n_cpus > 0);
138146

139-
const CPUInfo* p_cpu_info = &_global_platform_info.p_cpus[0];
147+
// Skip disabled
148+
size_t idx = 0;
149+
while (idx < _global_platform_info.n_cpus && !_cpuIdxIsEligible(idx)) {
150+
trace("Skipping idx %zu (CPU %d)", idx, _global_platform_info.p_cpus[idx].logical_cpu_num);
151+
++idx;
152+
}
153+
154+
if (idx >= _global_platform_info.n_cpus) {
155+
panic("No cpus assigned to this process");
156+
}
140157

141-
for (size_t idx = 0; idx < _global_platform_info.n_cpus; ++idx) {
158+
const CPUInfo* p_cpu_info = &_global_platform_info.p_cpus[idx++];
159+
160+
for (; idx < _global_platform_info.n_cpus; ++idx) {
142161
const CPUInfo* rhs = &_global_platform_info.p_cpus[idx];
143-
if (_cpuinfo_compare(p_cpu_info, rhs) == 1) {
162+
if (_cpuIdxIsEligible(idx) && _cpuinfo_compare(p_cpu_info, rhs) == 1) {
144163
// In this case, rhs is preferred to lhs
145164
p_cpu_info = rhs;
146165
}
@@ -333,6 +352,17 @@ static void _global_platform_info_hash_tables_init() {
333352
}
334353
}
335354

355+
static cpu_set_t* _getAffinity(size_t cpu_num) {
356+
size_t cpu_set_size = CPU_ALLOC_SIZE(cpu_num);
357+
cpu_set_t* cpu_set = CPU_ALLOC(cpu_num);
358+
359+
int rc = sched_getaffinity(0, cpu_set_size, cpu_set);
360+
if (rc < 0) {
361+
panic("sched_getaffinity: %s", strerror(errno));
362+
}
363+
return cpu_set;
364+
}
365+
336366
int affinity_initPlatformInfo() {
337367

338368
char* lscpu_contents = NULL;
@@ -352,6 +382,8 @@ int affinity_initPlatformInfo() {
352382
return -1;
353383
}
354384

385+
_global_platform_info.initial_affinity = _getAffinity(_global_platform_info.n_cpus);
386+
355387
_global_platform_info_hash_tables_init();
356388

357389
// Derive the max CPU number and fill the queue.

0 commit comments

Comments
 (0)