Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 35 additions & 34 deletions src/main/java/ca/spottedleaf/concurrentutil/numa/LinuxNuma.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,59 +25,60 @@ public final class LinuxNuma extends OSNuma.PreCalculatedNuma {
}
public static final LinuxNuma INSTANCE;
static {
if (!LIBRARIES_AVAILABLE) {
INSTANCE = null;
} else {
LinuxNuma instance = null;
if (LIBRARIES_AVAILABLE) {
final int totalNumaNodes = LibNuma.numa_max_node() + 1;

final Pointer cpuMask = LibNuma.numa_allocate_cpumask();
try {
if (cpuMask == null) {
INSTANCE = null;
} else {
if (cpuMask != null) {
final int totalCpus = LibNuma.numa_num_possible_cpus();

int[] coreToNuma = new int[0];
for (int node = 0; node < totalNumaNodes; ++node) {
LibNuma.numa_bitmask_clearall(cpuMask);
final int res = LibNuma.numa_node_to_cpus(node, cpuMask);
if (res != 0) {
// failed
coreToNuma = null;
break;
}

for (int cpu = 0; cpu < totalCpus; ++cpu) {
final int bit = LibNuma.numa_bitmask_isbitset(cpuMask, cpu);
if (bit == 0) {
// not set
continue;
if (totalCpus > 0) {
final int[] coreToNuma = new int[totalCpus];
Arrays.fill(coreToNuma, -1);

boolean ok = true;
for (int node = 0; node < totalNumaNodes; ++node) {
LibNuma.numa_bitmask_clearall(cpuMask);
final int res = LibNuma.numa_node_to_cpus(node, cpuMask);
if (res != 0) {
// failed to gather topology
ok = false;
break;
}
// it is set, so mark it in the core mapping
if (coreToNuma.length <= cpu) {
coreToNuma = Arrays.copyOf(coreToNuma, cpu + 1);

for (int cpu = 0; cpu < totalCpus; ++cpu) {
final int bit = LibNuma.numa_bitmask_isbitset(cpuMask, cpu);
if (bit == 0) {
// not set
continue;
}
// it is set, so mark it in the core mapping
coreToNuma[cpu] = node;
}
}
}

final int[][] costArray = new int[totalNumaNodes][totalNumaNodes];
for (int i = 0; i < totalNumaNodes; ++i) {
for (int j = 0; j < totalNumaNodes; ++j) {
final int dist = LibNuma.numa_distance(i, j);
// distance is 0 when it cannot be determined
costArray[i][j] = dist <= 0 ? 255 : dist;
if (ok) {
final int[][] costArray = new int[totalNumaNodes][totalNumaNodes];
for (int i = 0; i < totalNumaNodes; ++i) {
for (int j = 0; j < totalNumaNodes; ++j) {
final int dist = LibNuma.numa_distance(i, j);
// distance is 0 when it cannot be determined
costArray[i][j] = dist <= 0 ? 255 : dist;
}
}

instance = new LinuxNuma(coreToNuma, costArray);
}
}

INSTANCE = coreToNuma == null ? null : new LinuxNuma(coreToNuma, costArray);
}
} finally {
if (cpuMask != null) {
LibNuma.numa_bitmask_free(cpuMask);
}
}
}
INSTANCE = instance;
}

private LinuxNuma(final int[] coreToNuma, final int[][] costArray) {
Expand Down
22 changes: 18 additions & 4 deletions src/main/java/ca/spottedleaf/concurrentutil/numa/OSNuma.java
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,11 @@ public default void setCurrentNumaAffinity(final long[] to) {
public default void setCurrentNumaAffinity(final int[] numaNodes) {
final IntArrayList cores = new IntArrayList();
for (final int node : numaNodes) {
cores.addAll(IntArrayList.wrap(this.getCores(node)));
final int[] nodeCores = this.getCores(node);
if (nodeCores == null) {
throw new IllegalArgumentException("Unknown NUMA node: " + node);
}
cores.addAll(IntArrayList.wrap(nodeCores));
}

this.setCurrentThreadAffinity(FlatBitsetUtil.intsToBitset(cores.toIntArray()));
Expand All @@ -151,7 +155,12 @@ public PreCalculatedNuma(final int[] coreToNuma, final int[][] costArray) {
}

for (int core = 0; core < coreToNuma.length; ++core) {
numaToCore[coreToNuma[core]].add(core);
final int node = coreToNuma[core];
if (node < 0 || node >= numaToCore.length) {
// unknown mapping, ignore
continue;
}
numaToCore[node].add(core);
}

this.numaToCore = new int[this.costArray.length][];
Expand Down Expand Up @@ -195,7 +204,12 @@ public int getNumaNode(final int coreId) {
// cannot determine
return -1;
}
return this.coreToNuma[coreId];
final int node = this.coreToNuma[coreId];
if (node < 0 || node >= this.costArray.length) {
// cannot determine
return -1;
}
return node;
}

@Override
Expand All @@ -214,7 +228,7 @@ public int[] getCores(final int numaId) {

@Override
public int getCurrentNumaNode() {
return this.coreToNuma[this.getCurrentCore()];
return this.getNumaNode(this.getCurrentCore());
}
}

Expand Down