summaryrefslogtreecommitdiff
path: root/src/gc
diff options
context:
space:
mode:
authorJan Vorlicek <janvorli@microsoft.com>2019-04-26 11:53:41 +0200
committerJan Vorlicek <janvorli@microsoft.com>2019-04-26 13:55:11 +0200
commit9733c30b27ca90d3eeb07928df6e6e5861c203bb (patch)
tree32588addecdfeac9401f3aa232af0d48328c491f /src/gc
parent9957d039a2ac69bf42fac51b45abae48c1c212d0 (diff)
downloadcoreclr-9733c30b27ca90d3eeb07928df6e6e5861c203bb.tar.gz
coreclr-9733c30b27ca90d3eeb07928df6e6e5861c203bb.tar.bz2
coreclr-9733c30b27ca90d3eeb07928df6e6e5861c203bb.zip
Fix creation of the NUMA node to heap number map
The current implementation assumes that the NUMA nodes of CPUs used for GC threads form a zero based continous range. However that doesn't have to be true for cases when user selects only a subset of the available CPUs for the GC heap threads using the COMPlus_GCHeapAffinitizeMask or COMPlus_GCHeapAffinitizeRanges. The selected CPUs may belong only to a subset of NUMA nodes that don't necessarily start at node 0 or form a continuous range. This change fixes the algorithm that initializes the numa_node_to_heap_map lookup array so that it works correctly even in such cases.
Diffstat (limited to 'src/gc')
-rw-r--r--src/gc/gc.cpp26
1 files changed, 17 insertions, 9 deletions
diff --git a/src/gc/gc.cpp b/src/gc/gc.cpp
index bcffca016b..b3bb610be4 100644
--- a/src/gc/gc.cpp
+++ b/src/gc/gc.cpp
@@ -5195,23 +5195,31 @@ public:
}
static void init_numa_node_to_heap_map(int nheaps)
- { // called right after GCHeap::Init() for each heap is finished
- // when numa is not enabled, heap_no_to_numa_node[] are all filled
- // with 0s during initialization, and will be treated as one node
- numa_node_to_heap_map[0] = 0;
- int node_index = 1;
+ { // Called right after GCHeap::Init() for each heap
+ // For each NUMA node used by the heaps, the
+ // numa_node_to_heap_map[numa_node] is set to the first heap number on that node and
+ // numa_node_to_heap_map[numa_node + 1] is set to the first heap number not on that node
+
+ // Set the start of the heap number range for the first NUMA node
+ numa_node_to_heap_map[heap_no_to_numa_node[0]] = 0;
for (int i=1; i < nheaps; i++)
{
if (heap_no_to_numa_node[i] != heap_no_to_numa_node[i-1])
- numa_node_to_heap_map[node_index++] = (uint16_t)i;
+ {
+ // Set the end of the heap number range for the previous NUMA node
+ numa_node_to_heap_map[heap_no_to_numa_node[i-1] + 1] =
+ // Set the start of the heap number range for the current NUMA node
+ numa_node_to_heap_map[heap_no_to_numa_node[i]] = (uint16_t)i;
+ }
}
- numa_node_to_heap_map[node_index] = (uint16_t)nheaps; //mark the end with nheaps
+
+ // Set the end of the heap range for the last NUMA node
+ numa_node_to_heap_map[heap_no_to_numa_node[nheaps-1] + 1] = (uint16_t)nheaps; //mark the end with nheaps
}
static void get_heap_range_for_heap(int hn, int* start, int* end)
- { // 1-tier/no numa case: heap_no_to_numa_node[] all zeros,
- // and treated as in one node. thus: start=0, end=n_heaps
+ {
uint16_t numa_node = heap_no_to_numa_node[hn];
*start = (int)numa_node_to_heap_map[numa_node];
*end = (int)(numa_node_to_heap_map[numa_node+1]);