Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
Merged
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
6 changes: 6 additions & 0 deletions src/gc/env/gcenv.interlocked.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ class Interlocked
template<typename T>
static T ExchangeAdd(T volatile *addend, T value);

template<typename T>
static T ExchangeAdd64(T volatile* addend, T value);

template<typename T>
static T ExchangeAddPtr(T volatile* addend, T value);

// Performs an atomic compare-and-exchange operation on the specified values.
// Parameters:
// destination - value to be exchanged
Expand Down
31 changes: 31 additions & 0 deletions src/gc/env/gcenv.interlocked.inl
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,37 @@ __forceinline T Interlocked::ExchangeAdd(T volatile *addend, T value)
#endif
}

template <typename T>
__forceinline T Interlocked::ExchangeAdd64(T volatile* addend, T value)
{
#ifdef _MSC_VER
static_assert(sizeof(int64_t) == sizeof(T), "Size of LONGLONG must be the same as size of T");
return _InterlockedExchangeAdd64((int64_t*)addend, value);
#else
T result = __sync_fetch_and_add(addend, value);
ArmInterlockedOperationBarrier();
return result;
#endif
}

template <typename T>
__forceinline T Interlocked::ExchangeAddPtr(T volatile* addend, T value)
{
#ifdef _MSC_VER
#ifdef BIT64
static_assert(sizeof(int64_t) == sizeof(T), "Size of LONGLONG must be the same as size of T");
return _InterlockedExchangeAdd64((int64_t*)addend, value);
#else
static_assert(sizeof(long) == sizeof(T), "Size of long must be the same as size of T");
return _InterlockedExchangeAdd((long*)addend, value);
#endif
#else
T result = __sync_fetch_and_add(addend, value);
ArmInterlockedOperationBarrier();
return result;
#endif
}

// Perform an atomic AND operation on the specified values values
// Parameters:
// destination - the first operand and the destination
Expand Down
19 changes: 18 additions & 1 deletion src/gc/env/gcenv.os.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,10 @@ typedef void (*GCThreadFunction)(void* param);
// 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
#define MAX_SUPPORTED_NODES 64
#else
#define MAX_SUPPORTED_CPUS 64
#define MAX_SUPPORTED_NODES 16
#endif // BIT64

// Add of processor indices used to store affinity.
Expand Down Expand Up @@ -253,6 +255,7 @@ class GCToOSInterface
// size - size of the virtual memory range
// alignment - requested memory alignment
// flags - flags to control special settings like write watching
// node - the NUMA node to reserve memory on
// Return:
// Starting virtual address of the reserved range
// Notes:
Expand All @@ -264,7 +267,7 @@ class GCToOSInterface
//
// Windows guarantees that the returned mapping will be aligned to the allocation
// granularity.
static void* VirtualReserve(size_t size, size_t alignment, uint32_t flags);
static void* VirtualReserve(size_t size, size_t alignment, uint32_t flags, uint16_t node = NUMA_NODE_UNDEFINED);

// Release virtual memory range previously reserved using VirtualReserve
// Parameters:
Expand Down Expand Up @@ -360,6 +363,8 @@ class GCToOSInterface
// true if it has succeeded, false if it has failed
static bool SetCurrentThreadIdealAffinity(uint16_t srcProcNo, uint16_t dstProcNo);

static bool GetCurrentThreadIdealProc(uint16_t* procNo);

// Get numeric id of the current thread if possible on the
// current platform. It is indended for logging purposes only.
// Return:
Expand Down Expand Up @@ -484,6 +489,15 @@ class GCToOSInterface
// Is NUMA support available
static bool CanEnableGCNumaAware();

// TODO: add Linux implementation.
// For no NUMA this returns false.
static bool GetNumaInfo(uint16_t* total_nodes, uint32_t* max_procs_per_node);

// Is CPU Group enabled
// This only applies on Windows and only used by instrumentation but is on the
// interface due to LocalGC.
static bool CanEnableGCCPUGroups();

// Get processor number and optionally its NUMA node number for the specified heap number
// Parameters:
// heap_number - heap number to get the result for
Expand All @@ -493,6 +507,9 @@ class GCToOSInterface
// true if it succeeded
static bool GetProcessorForHeap(uint16_t heap_number, uint16_t* proc_no, uint16_t* node_no);

// For no CPU groups this returns false.
static bool GetCPUGroupInfo(uint16_t* total_groups, uint32_t* max_procs_per_group);

// Parse the confing string describing affinitization ranges and update the passed in affinitySet accordingly
// Parameters:
// config_string - string describing the affinitization range, platform specific
Expand Down
Loading