summaryrefslogtreecommitdiff
path: root/src/gc/sample/gcenv.windows.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gc/sample/gcenv.windows.cpp')
-rw-r--r--src/gc/sample/gcenv.windows.cpp453
1 files changed, 0 insertions, 453 deletions
diff --git a/src/gc/sample/gcenv.windows.cpp b/src/gc/sample/gcenv.windows.cpp
deleted file mode 100644
index 76187f2185..0000000000
--- a/src/gc/sample/gcenv.windows.cpp
+++ /dev/null
@@ -1,453 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-//
-// Implementation of the GC environment
-//
-
-#include "common.h"
-
-#include "windows.h"
-
-#include "gcenv.h"
-#include "gc.h"
-
-MethodTable * g_pFreeObjectMethodTable;
-
-int32_t g_TrapReturningThreads;
-
-bool g_fFinalizerRunOnShutDown;
-
-GCSystemInfo g_SystemInfo;
-
-static LARGE_INTEGER g_performanceFrequency;
-
-// Initialize the interface implementation
-// Return:
-// true if it has succeeded, false if it has failed
-bool GCToOSInterface::Initialize()
-{
- if (!::QueryPerformanceFrequency(&g_performanceFrequency))
- {
- return false;
- }
-
- SYSTEM_INFO systemInfo;
- GetSystemInfo(&systemInfo);
-
- g_SystemInfo.dwNumberOfProcessors = systemInfo.dwNumberOfProcessors;
- g_SystemInfo.dwPageSize = systemInfo.dwPageSize;
- g_SystemInfo.dwAllocationGranularity = systemInfo.dwAllocationGranularity;
-
- return true;
-}
-
-// Shutdown the interface implementation
-void GCToOSInterface::Shutdown()
-{
-}
-
-// Get numeric id of the current thread if possible on the
-// current platform. It is indended for logging purposes only.
-// Return:
-// Numeric id of the current thread or 0 if the
-uint64_t GCToOSInterface::GetCurrentThreadIdForLogging()
-{
- return ::GetCurrentThreadId();
-}
-
-// Get id of the process
-// Return:
-// Id of the current process
-uint32_t GCToOSInterface::GetCurrentProcessId()
-{
- return ::GetCurrentProcessId();
-}
-
-// Set ideal affinity for the current thread
-// Parameters:
-// affinity - ideal processor affinity for the thread
-// Return:
-// true if it has succeeded, false if it has failed
-bool GCToOSInterface::SetCurrentThreadIdealAffinity(GCThreadAffinity* affinity)
-{
- bool success = true;
-
-#if !defined(FEATURE_CORESYSTEM)
- SetThreadIdealProcessor(GetCurrentThread(), (DWORD)affinity->Processor);
-#else
- PROCESSOR_NUMBER proc;
-
- if (affinity->Group != -1)
- {
- proc.Group = (WORD)affinity->Group;
- proc.Number = (BYTE)affinity->Processor;
- proc.Reserved = 0;
-
- success = !!SetThreadIdealProcessorEx(GetCurrentThread(), &proc, NULL);
- }
- else
- {
- if (GetThreadIdealProcessorEx(GetCurrentThread(), &proc))
- {
- proc.Number = affinity->Processor;
- success = !!SetThreadIdealProcessorEx(GetCurrentThread(), &proc, NULL);
- }
- }
-#endif
-
- return success;
-}
-
-// Get the number of the current processor
-uint32_t GCToOSInterface::GetCurrentProcessorNumber()
-{
- _ASSERTE(GCToOSInterface::CanGetCurrentProcessorNumber());
- return ::GetCurrentProcessorNumber();
-}
-
-// Check if the OS supports getting current processor number
-bool GCToOSInterface::CanGetCurrentProcessorNumber()
-{
- return true;
-}
-
-// Flush write buffers of processors that are executing threads of the current process
-void GCToOSInterface::FlushProcessWriteBuffers()
-{
- ::FlushProcessWriteBuffers();
-}
-
-// Break into a debugger
-void GCToOSInterface::DebugBreak()
-{
- ::DebugBreak();
-}
-
-// Get number of logical processors
-uint32_t GCToOSInterface::GetLogicalCpuCount()
-{
- return g_SystemInfo.dwNumberOfProcessors;
-}
-
-// Causes the calling thread to sleep for the specified number of milliseconds
-// Parameters:
-// sleepMSec - time to sleep before switching to another thread
-void GCToOSInterface::Sleep(uint32_t sleepMSec)
-{
- ::Sleep(sleepMSec);
-}
-
-// Causes the calling thread to yield execution to another thread that is ready to run on the current processor.
-// Parameters:
-// switchCount - number of times the YieldThread was called in a loop
-void GCToOSInterface::YieldThread(uint32_t switchCount)
-{
- SwitchToThread();
-}
-
-// Reserve virtual memory range.
-// Parameters:
-// address - starting virtual address, it can be NULL to let the function choose the starting address
-// size - size of the virtual memory range
-// alignment - requested memory alignment
-// flags - flags to control special settings like write watching
-// Return:
-// Starting virtual address of the reserved range
-void* GCToOSInterface::VirtualReserve(void* address, size_t size, size_t alignment, uint32_t flags)
-{
- DWORD memFlags = (flags & VirtualReserveFlags::WriteWatch) ? (MEM_RESERVE | MEM_WRITE_WATCH) : MEM_RESERVE;
- return ::VirtualAlloc(0, size, memFlags, PAGE_READWRITE);
-}
-
-// Release virtual memory range previously reserved using VirtualReserve
-// Parameters:
-// address - starting virtual address
-// size - size of the virtual memory range
-// Return:
-// true if it has succeeded, false if it has failed
-bool GCToOSInterface::VirtualRelease(void* address, size_t size)
-{
- UNREFERENCED_PARAMETER(size);
- return !!::VirtualFree(address, 0, MEM_RELEASE);
-}
-
-// Commit virtual memory range. It must be part of a range reserved using VirtualReserve.
-// Parameters:
-// address - starting virtual address
-// size - size of the virtual memory range
-// Return:
-// true if it has succeeded, false if it has failed
-bool GCToOSInterface::VirtualCommit(void* address, size_t size)
-{
- return ::VirtualAlloc(address, size, MEM_COMMIT, PAGE_READWRITE) != NULL;
-}
-
-// Decomit virtual memory range.
-// Parameters:
-// address - starting virtual address
-// size - size of the virtual memory range
-// Return:
-// true if it has succeeded, false if it has failed
-bool GCToOSInterface::VirtualDecommit(void* address, size_t size)
-{
- return !!::VirtualFree(address, size, MEM_DECOMMIT);
-}
-
-// Reset virtual memory range. Indicates that data in the memory range specified by address and size is no
-// longer of interest, but it should not be decommitted.
-// Parameters:
-// address - starting virtual address
-// size - size of the virtual memory range
-// unlock - true if the memory range should also be unlocked
-// Return:
-// true if it has succeeded, false if it has failed
-bool GCToOSInterface::VirtualReset(void * address, size_t size, bool unlock)
-{
- bool success = ::VirtualAlloc(address, size, MEM_RESET, PAGE_READWRITE) != NULL;
- if (success && unlock)
- {
- // Remove the page range from the working set
- ::VirtualUnlock(address, size);
- }
-
- return success;
-}
-
-// Check if the OS supports write watching
-bool GCToOSInterface::SupportsWriteWatch()
-{
- return false;
-}
-
-// Reset the write tracking state for the specified virtual memory range.
-// Parameters:
-// address - starting virtual address
-// size - size of the virtual memory range
-void GCToOSInterface::ResetWriteWatch(void* address, size_t size)
-{
-}
-
-// Retrieve addresses of the pages that are written to in a region of virtual memory
-// Parameters:
-// resetState - true indicates to reset the write tracking state
-// address - starting virtual address
-// size - size of the virtual memory range
-// pageAddresses - buffer that receives an array of page addresses in the memory region
-// pageAddressesCount - on input, size of the lpAddresses array, in array elements
-// on output, the number of page addresses that are returned in the array.
-// Return:
-// true if it has succeeded, false if it has failed
-bool GCToOSInterface::GetWriteWatch(bool resetState, void* address, size_t size, void** pageAddresses, uintptr_t* pageAddressesCount)
-{
- return false;
-}
-
-// Get size of the largest cache on the processor die
-// Parameters:
-// trueSize - true to return true cache size, false to return scaled up size based on
-// the processor architecture
-// Return:
-// Size of the cache
-size_t GCToOSInterface::GetLargestOnDieCacheSize(bool trueSize)
-{
- // TODO: implement
- return 0;
-}
-
-// Get affinity mask of the current process
-// Parameters:
-// processMask - affinity mask for the specified process
-// systemMask - affinity mask for the system
-// 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.
-bool GCToOSInterface::GetCurrentProcessAffinityMask(uintptr_t* processMask, uintptr_t* systemMask)
-{
- return false;
-}
-
-// Get number of processors assigned to the current process
-// Return:
-// The number of processors
-uint32_t GCToOSInterface::GetCurrentProcessCpuCount()
-{
- return g_SystemInfo.dwNumberOfProcessors;
-}
-
-// Return the size of the user-mode portion of the virtual address space of this process.
-// Return:
-// non zero if it has succeeded, 0 if it has failed
-size_t GCToOSInterface::GetVirtualMemoryLimit()
-{
- MEMORYSTATUSEX memStatus;
-
- memStatus.dwLength = sizeof(MEMORYSTATUSEX);
- BOOL fRet = GlobalMemoryStatusEx(&memStatus);
- _ASSERTE(fRet);
-
- return (size_t)memStatus.ullTotalVirtual;
-}
-
-// Get the physical memory that this process can use.
-// Return:
-// non zero if it has succeeded, 0 if it has failed
-uint64_t GCToOSInterface::GetPhysicalMemoryLimit()
-{
- MEMORYSTATUSEX memStatus;
-
- memStatus.dwLength = sizeof(MEMORYSTATUSEX);
- BOOL fRet = GlobalMemoryStatusEx(&memStatus);
- _ASSERTE(fRet);
-
- return memStatus.ullTotalPhys;
-}
-
-// Get memory status
-// Parameters:
-// memory_load - A number between 0 and 100 that specifies the approximate percentage of physical memory
-// that is in use (0 indicates no memory use and 100 indicates full memory use).
-// available_physical - The amount of physical memory currently available, in bytes.
-// available_page_file - The maximum amount of memory the current process can commit, in bytes.
-void GCToOSInterface::GetMemoryStatus(uint32_t* memory_load, uint64_t* available_physical, uint64_t* available_page_file)
-{
- MEMORYSTATUSEX memStatus;
-
- memStatus.dwLength = sizeof(MEMORYSTATUSEX);
- BOOL fRet = GlobalMemoryStatusEx(&memStatus);
- _ASSERTE (fRet);
-
- // If the machine has more RAM than virtual address limit, let us cap it.
- // The GC can never use more than virtual address limit.
- if (memStatus.ullAvailPhys > memStatus.ullTotalVirtual)
- {
- memStatus.ullAvailPhys = memStatus.ullAvailVirtual;
- }
-
- if (memory_load != NULL)
- *memory_load = memStatus.dwMemoryLoad;
- if (available_physical != NULL)
- *available_physical = memStatus.ullAvailPhys;
- if (available_page_file != NULL)
- *available_page_file = memStatus.ullAvailPageFile;
-}
-
-// Get a high precision performance counter
-// Return:
-// The counter value
-int64_t GCToOSInterface::QueryPerformanceCounter()
-{
- LARGE_INTEGER ts;
- if (!::QueryPerformanceCounter(&ts))
- {
- _ASSERTE(!"Fatal Error - cannot query performance counter.");
- abort();
- }
-
- return ts.QuadPart;
-}
-
-// Get a frequency of the high precision performance counter
-// Return:
-// The counter frequency
-int64_t GCToOSInterface::QueryPerformanceFrequency()
-{
- return g_performanceFrequency.QuadPart;
-}
-
-// Get a time stamp with a low precision
-// Return:
-// Time stamp in milliseconds
-uint32_t GCToOSInterface::GetLowPrecisionTimeStamp()
-{
- return ::GetTickCount();
-}
-
-// Parameters of the GC thread stub
-struct GCThreadStubParam
-{
- GCThreadFunction GCThreadFunction;
- void* GCThreadParam;
-};
-
-// GC thread stub to convert GC thread function to an OS specific thread function
-static DWORD __stdcall GCThreadStub(void* param)
-{
- GCThreadStubParam *stubParam = (GCThreadStubParam*)param;
- GCThreadFunction function = stubParam->GCThreadFunction;
- void* threadParam = stubParam->GCThreadParam;
-
- delete stubParam;
-
- function(threadParam);
-
- return 0;
-}
-
-// Create a new thread
-// Parameters:
-// function - the function to be executed by the thread
-// param - parameters of the thread
-// affinity - processor affinity of the thread
-// Return:
-// true if it has succeeded, false if it has failed
-bool GCToOSInterface::CreateThread(GCThreadFunction function, void* param, GCThreadAffinity* affinity)
-{
- DWORD thread_id;
-
- GCThreadStubParam* stubParam = new (nothrow) GCThreadStubParam();
- if (stubParam == NULL)
- {
- return false;
- }
-
- stubParam->GCThreadFunction = function;
- stubParam->GCThreadParam = param;
-
- HANDLE gc_thread = ::CreateThread(NULL, 0, GCThreadStub, stubParam, CREATE_SUSPENDED, &thread_id);
-
- if (!gc_thread)
- {
- delete stubParam;
- return false;
- }
-
- SetThreadPriority(gc_thread, /* THREAD_PRIORITY_ABOVE_NORMAL );*/ THREAD_PRIORITY_HIGHEST );
-
- ResumeThread(gc_thread);
-
- CloseHandle(gc_thread);
-
- return true;
-}
-
-// Initialize the critical section
-void CLRCriticalSection::Initialize()
-{
- ::InitializeCriticalSection(&m_cs);
-}
-
-// Destroy the critical section
-void CLRCriticalSection::Destroy()
-{
- ::DeleteCriticalSection(&m_cs);
-}
-
-// Enter the critical section. Blocks until the section can be entered.
-void CLRCriticalSection::Enter()
-{
- ::EnterCriticalSection(&m_cs);
-}
-
-// Leave the critical section
-void CLRCriticalSection::Leave()
-{
- ::LeaveCriticalSection(&m_cs);
-}