Switch GCSample to the canonical GCToOSInterface implementation (#8653)
authorJan Kotas <jkotas@microsoft.com>
Thu, 15 Dec 2016 22:26:48 +0000 (14:26 -0800)
committerGitHub <noreply@github.com>
Thu, 15 Dec 2016 22:26:48 +0000 (14:26 -0800)
src/gc/gcenv.unix.cpp
src/gc/gcenv.windows.cpp
src/gc/sample/CMakeLists.txt
src/gc/sample/GCSample.vcxproj
src/gc/sample/GCSample.vcxproj.filters
src/gc/sample/gcenv.ee.cpp
src/gc/sample/gcenv.unix.cpp [deleted file]
src/gc/sample/gcenv.windows.cpp [deleted file]

index 8263ded..0235952 100644 (file)
@@ -6,8 +6,6 @@
 #include "env/gcenv.base.h"
 #include "env/gcenv.os.h"
 
-#error This file should not be compiled!
-
 // Initialize the interface implementation
 // Return:
 //  true if it has succeeded, false if it has failed
index 3377655..a636478 100644 (file)
 #include "env/gcenv.base.h"
 #include "env/gcenv.os.h"
 
-#ifndef FEATURE_STANDALONE_GC
-#error This file should only be compiled for a standalone GC
-#endif // FEATURE_STANDALONE_GC
-
 GCSystemInfo g_SystemInfo;
 
 typedef BOOL (WINAPI *PGET_PROCESS_MEMORY_INFO)(HANDLE handle, PROCESS_MEMORY_COUNTERS* memCounters, uint32_t cb);
@@ -422,7 +418,7 @@ size_t GCToOSInterface::GetVirtualMemoryLimit()
     MEMORYSTATUSEX memStatus;
     if (::GlobalMemoryStatusEx(&memStatus))
     {
-        return memStatus.ullAvailVirtual;
+        return (size_t)memStatus.ullAvailVirtual;
     }
 
     return 0;
index 572fba3..9552cc5 100644 (file)
@@ -22,11 +22,11 @@ set(SOURCES
 
 if(WIN32)
     list(APPEND SOURCES
-        gcenv.windows.cpp)
+        ../gcenv.windows.cpp)
     add_definitions(-DUNICODE=1)
 else()
     list(APPEND SOURCES
-        gcenv.unix.cpp)
+        ../gcenv.unix.cpp)
 endif()
 
 _add_executable(gcsample
index b196e1f..1716f46 100644 (file)
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="gcenv.ee.cpp" />
-    <ClCompile Include="gcenv.windows.cpp" />
     <ClCompile Include="GCSample.cpp" />
     <ClCompile Include="..\gccommon.cpp" />
     <ClCompile Include="..\gceewks.cpp" />
+    <ClCompile Include="..\gcenv.windows.cpp">
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+    </ClCompile>
     <ClCompile Include="..\gcscan.cpp" />
     <ClCompile Include="..\gcwks.cpp" />
     <ClCompile Include="..\handletable.cpp" />
@@ -96,8 +98,7 @@
     <ClCompile Include="..\handletablescan.cpp" />
     <ClCompile Include="..\objecthandle.cpp" />
     <ClCompile Include="..\env\common.cpp">
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
-      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader>Create</PrecompiledHeader>
     </ClCompile>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
index e46c054..f6aacfd 100644 (file)
@@ -59,7 +59,7 @@
     <ClCompile Include="gcenv.ee.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="gcenv.windows.cpp">
+    <ClCompile Include="..\gcenv.windows.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
   </ItemGroup>
index 51a735c..ac227b4 100644 (file)
@@ -9,6 +9,12 @@
 #include "gcenv.h"
 #include "gc.h"
 
+MethodTable * g_pFreeObjectMethodTable;
+
+int32_t g_TrapReturningThreads;
+
+bool g_fFinalizerRunOnShutDown;
+
 EEConfig * g_pConfig;
 
 bool CLREventStatic::CreateManualEventNoThrow(bool bInitialState)
diff --git a/src/gc/sample/gcenv.unix.cpp b/src/gc/sample/gcenv.unix.cpp
deleted file mode 100644 (file)
index a5e9e83..0000000
+++ /dev/null
@@ -1,14 +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 "gcenv.h"
-#include "gc.h"
-
-// TODO: Implement
diff --git a/src/gc/sample/gcenv.windows.cpp b/src/gc/sample/gcenv.windows.cpp
deleted file mode 100644 (file)
index a14019d..0000000
+++ /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(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);
-}