summaryrefslogtreecommitdiff
path: root/src/gc/env/gcenv.os.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/gc/env/gcenv.os.h')
-rw-r--r--src/gc/env/gcenv.os.h143
1 files changed, 102 insertions, 41 deletions
diff --git a/src/gc/env/gcenv.os.h b/src/gc/env/gcenv.os.h
index 3224f71d9d..f4dddb86f5 100644
--- a/src/gc/env/gcenv.os.h
+++ b/src/gc/env/gcenv.os.h
@@ -24,7 +24,7 @@
#define YieldProcessor System_YieldProcessor
#endif
-#define NUMA_NODE_UNDEFINED UINT32_MAX
+#define NUMA_NODE_UNDEFINED UINT16_MAX
// Critical section used by the GC
class CLRCriticalSection
@@ -55,17 +55,6 @@ struct VirtualReserveFlags
};
};
-// Affinity of a GC thread
-struct GCThreadAffinity
-{
- static const int None = -1;
-
- // Processor group index, None if no group is specified
- int Group;
- // Processor index, None if no affinity is specified
- int Processor;
-};
-
// An event is a synchronization object whose state can be set and reset
// indicating that an event has occured. It is used pervasively throughout
// the GC.
@@ -149,6 +138,86 @@ public:
// GC thread function prototype
typedef void (*GCThreadFunction)(void* param);
+#ifdef BIT64
+// Right now we support maximum 1024 procs - meaning that we will create at most
+// that many GC threads and GC heaps.
+#define MAX_SUPPORTED_CPUS 1024
+#else
+#define MAX_SUPPORTED_CPUS 64
+#endif // BIT64
+
+// Add of processor indices used to store affinity.
+class AffinitySet
+{
+ static const size_t BitsPerBitsetEntry = 8 * sizeof(uintptr_t);
+
+ uintptr_t m_bitset[MAX_SUPPORTED_CPUS / BitsPerBitsetEntry];
+
+ uintptr_t GetBitsetEntryMask(size_t cpuIndex)
+ {
+ return (uintptr_t)1 << (cpuIndex & (BitsPerBitsetEntry - 1));
+ }
+
+ size_t GetBitsetEntryIndex(size_t cpuIndex)
+ {
+ return cpuIndex / BitsPerBitsetEntry;
+ }
+
+public:
+
+ AffinitySet()
+ {
+ memset(m_bitset, 0, sizeof(m_bitset));
+ }
+
+ // Check if the set contains a processor
+ bool Contains(size_t cpuIndex)
+ {
+ return (m_bitset[GetBitsetEntryIndex(cpuIndex)] & GetBitsetEntryMask(cpuIndex)) != 0;
+ }
+
+ // Add a processor to the set
+ void Add(size_t cpuIndex)
+ {
+ m_bitset[GetBitsetEntryIndex(cpuIndex)] |= GetBitsetEntryMask(cpuIndex);
+ }
+
+ // Remove a processor from the set
+ void Remove(size_t cpuIndex)
+ {
+ m_bitset[GetBitsetEntryIndex(cpuIndex)] &= ~GetBitsetEntryMask(cpuIndex);
+ }
+
+ // Check if the set is empty
+ bool IsEmpty()
+ {
+ for (size_t i = 0; i < MAX_SUPPORTED_CPUS / BitsPerBitsetEntry; i++)
+ {
+ if (m_bitset[i] != 0)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ // Return number of processors in the affinity set
+ size_t Count()
+ {
+ size_t count = 0;
+ for (size_t i = 0; i < MAX_SUPPORTED_CPUS; i++)
+ {
+ if (Contains(i))
+ {
+ count++;
+ }
+ }
+
+ return count;
+ }
+};
+
// Interface that the GC uses to invoke OS specific functionality
class GCToOSInterface
{
@@ -202,7 +271,7 @@ public:
// size - size of the virtual memory range
// Return:
// true if it has succeeded, false if it has failed
- static bool VirtualCommit(void *address, size_t size, uint32_t node = NUMA_NODE_UNDEFINED);
+ static bool VirtualCommit(void *address, size_t size, uint16_t node = NUMA_NODE_UNDEFINED);
// Decomit virtual memory range.
// Parameters:
@@ -267,13 +336,13 @@ public:
// Check if the OS supports getting current processor number
static bool CanGetCurrentProcessorNumber();
- // Set ideal processor for the current thread
+ // Add ideal processor for the current thread
// Parameters:
- // processorIndex - index of the processor in the group
- // affinity - ideal processor affinity for the thread
+ // srcProcNo - processor number the thread currently runs on
+ // dstProcNo - processor number the thread should be migrated to
// Return:
// true if it has succeeded, false if it has failed
- static bool SetCurrentThreadIdealAffinity(GCThreadAffinity* affinity);
+ static bool MigrateThread(uint16_t srcProcNo, uint16_t dstProcNo);
// Get numeric id of the current thread if possible on the
// current platform. It is indended for logging purposes only.
@@ -303,14 +372,13 @@ public:
// The number of processors
static uint32_t GetCurrentProcessCpuCount();
- // Sets the calling thread's affinity to only run on the processor specified
- // in the GCThreadAffinity structure.
+ // Sets the calling thread's affinity to only run on the processor specified.
// Parameters:
- // affinity - The requested affinity for the calling thread. At most one processor
- // can be provided.
+ // procNo - The requested affinity for the calling thread.
+ //
// Return:
// true if setting the affinity was successful, false otherwise.
- static bool SetThreadAffinity(GCThreadAffinity* affinity);
+ static bool SetThreadAffinity(uint16_t procNo);
// Boosts the calling thread's thread priority to a level higher than the default
// for new threads.
@@ -320,20 +388,10 @@ public:
// true if the priority boost was successful, false otherwise.
static bool BoostThreadPriority();
- // Get affinity mask of the current process
- // Parameters:
- // processMask - affinity mask for the specified process
- // systemMask - affinity mask for the system
+ // Get set of processors enabled for GC for the current process
// Return:
- // true if it has succeeded, false if it has failed
- // Remarks:
- // A process affinity mask is a bit vector in which each bit represents the processors that
- // a process is allowed to run on. A system affinity mask is a bit vector in which each bit
- // represents the processors that are configured into a system.
- // A process affinity mask is a subset of the system affinity mask. A process is only allowed
- // to run on the processors configured into a system. Therefore, the process affinity mask cannot
- // specify a 1 bit for a processor when the system affinity mask specifies a 0 bit for that processor.
- static bool GetCurrentProcessAffinityMask(uintptr_t *processMask, uintptr_t *systemMask);
+ // set of enabled processors
+ static AffinitySet* GetCurrentProcessAffinitySet();
//
// Global memory info
@@ -408,13 +466,16 @@ public:
static bool CanEnableGCNumaAware();
// Gets the NUMA node for the processor
- static bool GetNumaProcessorNode(PPROCESSOR_NUMBER proc_no, uint16_t *node_no);
-
- // Are CPU groups enabled
- static bool CanEnableGCCPUGroups();
+ static bool GetNumaProcessorNode(uint16_t proc_no, uint16_t *node_no);
- // Get the CPU group for the specified processor
- static void GetGroupForProcessor(uint16_t processor_number, uint16_t* group_number, uint16_t* group_processor_number);
+ // Get processor number and optionally its NUMA node number for the specified heap number
+ // Parameters:
+ // heap_number - heap number to get the result for
+ // proc_no - set to the selected processor number
+ // node_no - set to the NUMA node of the selected processor or to NUMA_NODE_UNDEFINED
+ // Return:
+ // true if it succeeded
+ static bool GetProcessorForHeap(uint16_t heap_number, uint16_t* proc_no, uint16_t* node_no);
};