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
3839typedef 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+
336366int 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