33import com .sun .jna .*;
44import com .sun .jna .ptr .ByReference ;
55import com .sun .jna .ptr .IntByReference ;
6+ import org .slf4j .Logger ;
7+ import org .slf4j .LoggerFactory ;
68import java .util .Arrays ;
79
810public final class LinuxNuma extends OSNuma .PreCalculatedNuma {
911
12+ private static final Logger LOGGER = LoggerFactory .getLogger (LinuxNuma .class );
13+
1014 private static final ThreadLocal <IntByReference > CURRENT_CORE_POINTER = ThreadLocal .withInitial (IntByReference ::new );
1115 private static final boolean LIBRARIES_AVAILABLE ;
1216 static {
@@ -19,8 +23,11 @@ public final class LinuxNuma extends OSNuma.PreCalculatedNuma {
1923
2024 if (!librariesOk ) {
2125 LIBRARIES_AVAILABLE = false ;
26+ LOGGER .debug ("Unable to link NUMA libraries for Linux NUMA" );
2227 } else {
23- LIBRARIES_AVAILABLE = LibNuma .numa_available () >= 0 ;
28+ final int numaAvail = LibNuma .numa_available ();
29+ LIBRARIES_AVAILABLE = numaAvail >= 0 ;
30+ LOGGER .debug ("libnuma numa_available: " + numaAvail );
2431 }
2532 }
2633 public static final LinuxNuma INSTANCE ;
@@ -34,15 +41,19 @@ public final class LinuxNuma extends OSNuma.PreCalculatedNuma {
3441 try {
3542 if (cpuMask == null ) {
3643 INSTANCE = null ;
44+ LOGGER .debug ("Failed to create Linux NUMA CPU mapping: Failed to allocate cpu mask for libnuma" );
3745 } else {
3846 final int totalCpus = LibNuma .numa_num_possible_cpus ();
3947
40- int [] coreToNuma = new int [0 ];
48+ int [] coreToNuma = new int [totalCpus ];
49+ Arrays .fill (coreToNuma , -1 );
50+ core_to_numa_setup :
4151 for (int node = 0 ; node < totalNumaNodes ; ++node ) {
4252 LibNuma .numa_bitmask_clearall (cpuMask );
4353 final int res = LibNuma .numa_node_to_cpus (node , cpuMask );
4454 if (res != 0 ) {
4555 // failed
56+ LOGGER .debug ("Failed to create Linux NUMA CPU mapping: Failed libnuma numa_node_to_cpus(" + node + ", ...): " + res );
4657 coreToNuma = null ;
4758 break ;
4859 }
@@ -53,10 +64,22 @@ public final class LinuxNuma extends OSNuma.PreCalculatedNuma {
5364 // not set
5465 continue ;
5566 }
67+ if (coreToNuma [cpu ] != -1 ) {
68+ LOGGER .debug ("Failed to create Linux NUMA CPU mapping: Duplicate node mapping for core " + cpu + ": " + coreToNuma [cpu ] + " and " + node );
69+ coreToNuma = null ;
70+ break core_to_numa_setup ;
71+ }
5672 // it is set, so mark it in the core mapping
57- if (coreToNuma .length <= cpu ) {
58- coreToNuma = Arrays .copyOf (coreToNuma , cpu + 1 );
59- coreToNuma [cpu ] = node ;
73+ coreToNuma [cpu ] = node ;
74+ }
75+ }
76+ if (coreToNuma != null ) {
77+ for (int cpu = 0 ; cpu < coreToNuma .length ; ++cpu ) {
78+ final int node = coreToNuma [cpu ];
79+ if (node == -1 ) {
80+ LOGGER .debug ("Failed to create Linux NUMA CPU mapping: No node mapping for core " + cpu );
81+ coreToNuma = null ;
82+ break ;
6083 }
6184 }
6285 }
@@ -66,7 +89,8 @@ public final class LinuxNuma extends OSNuma.PreCalculatedNuma {
6689 for (int j = 0 ; j < totalNumaNodes ; ++j ) {
6790 final int dist = LibNuma .numa_distance (i , j );
6891 // distance is 0 when it cannot be determined
69- costArray [i ][j ] = dist <= 0 ? 255 : dist ;
92+ // distances 1-9 are reserved and have no meaning
93+ costArray [i ][j ] = dist < 10 ? OSNuma .NUMA_DISTANCE_CANNOT_DETERMINE : dist ;
7094 }
7195 }
7296
0 commit comments