diff --git a/azure-pipelines.yml b/azure-pipelines.yml index a207821a55..cff71d3e77 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1211,7 +1211,6 @@ jobs: - job: Run_UnitTests_mscorlib condition: >- and( - succeeded('Check_Code_Style'), succeeded('Build_nanoCLR_CLI'), ne(dependencies.Check_Build_Options.outputs['BuildOptions.SKIP_BUILD'], true), or( @@ -1284,6 +1283,35 @@ jobs: unitTestRunsettings: '$(System.DefaultWorkingDirectory)\nf-interpreter\targets\netcore\pipeline_tests.runsettings' packagesDirectory: '$(Build.SourcesDirectory)/CoreLibrary/packages' + - task: CopyFiles@2 + condition: succeededOrFailed() + displayName: Copy vstest dump files + inputs: + SourceFolder: 'D:\a\_temp\' + Contents: '**/*.dmp' + TargetFolder: '$(Build.ArtifactStagingDirectory)/vstest_dumps' + flattenFolders: true + + - powershell: | + $dumpPath = "$(Build.ArtifactStagingDirectory)/vstest_dumps" + $hasFiles = $false + + if (Test-Path $dumpPath -PathType Container) { + $fileCount = (Get-ChildItem $dumpPath -File | Measure-Object).Count + $hasFiles = $fileCount -gt 0 + } + echo "##vso[task.setvariable variable=hasFiles;isOutput=true]$hasFiles" + displayName: 'Check for dump files' + name: checkFiles + + - task: PublishPipelineArtifact@1 + condition: eq(variables['hasFiles'], 'true') + displayName: Publish vstest dump files + inputs: + targetPath: '$(Build.ArtifactStagingDirectory)/vstest_dumps' + artifactName: VsTestCrashDumps + artifactType: pipeline + ###################### # generate change log - job: Generate_change_log diff --git a/src/CLR/Core/Core.h b/src/CLR/Core/Core.h index 24d2169099..fc665f7908 100644 --- a/src/CLR/Core/Core.h +++ b/src/CLR/Core/Core.h @@ -8,17 +8,17 @@ #include #include -//#include +// #include #include -//#include -//#include -//#include +// #include +// #include +#include // -//#include +// #include // #include -//#include -//#include +// #include +// #include #include #endif // NANOCLR_CORE_H diff --git a/src/CLR/Include/nanoCLR_Application.h b/src/CLR/Include/nanoCLR_Application.h index 44a68ae689..f16384b358 100644 --- a/src/CLR/Include/nanoCLR_Application.h +++ b/src/CLR/Include/nanoCLR_Application.h @@ -32,7 +32,6 @@ typedef struct CLR_SETTINGS #if defined(VIRTUAL_DEVICE) bool PerformGarbageCollection; bool PerformHeapCompaction; - CLR_RT_StringVector StartArgs; #endif } CLR_SETTINGS; diff --git a/targets/netcore/nanoFramework.nanoCLR/CLRStartup.cpp b/targets/netcore/nanoFramework.nanoCLR/CLRStartup.cpp index 3899da5391..3e8eca7c93 100644 --- a/targets/netcore/nanoFramework.nanoCLR/CLRStartup.cpp +++ b/targets/netcore/nanoFramework.nanoCLR/CLRStartup.cpp @@ -24,30 +24,12 @@ struct Settings //--// - HRESULT Initialize(CLR_SETTINGS params) + HRESULT Initialize(CLR_SETTINGS const ¶ms) { NANOCLR_HEADER(); m_clrOptions = params; -#if defined(PLATFORM_WINDOWS_EMULATOR) - - CLR_UINT32 clockFrequencyBaseline = 27000000; - CLR_UINT32 clockFrequency = CPU_SystemClock(); - double clockFrequencyRatio = 1; - - if (clockFrequency > 0) - { - clockFrequencyRatio = (double)clockFrequencyBaseline / (double)clockFrequency; - } - - g_HAL_Configuration_Windows.ProductType = HAL_Configuration_Windows::Product_Aux; - g_HAL_Configuration_Windows.SlowClockPerSecond = 32768; - g_HAL_Configuration_Windows.TicksPerMethodCall = (CLR_UINT64)(45.0 * clockFrequencyRatio); - g_HAL_Configuration_Windows.TicksPerOpcode = (CLR_UINT64)(5.0 * clockFrequencyRatio); - g_HAL_Configuration_Windows.GraphHeapEnabled = false; -#endif - NANOCLR_CHECK_HRESULT(CLR_RT_ExecutionEngine::CreateInstance(params)); #if !defined(BUILD_RTM) CLR_Debug::Printf("Created EE.\r\n"); @@ -362,32 +344,6 @@ struct Settings m_assemblies.clear(); // CLR_RT_ParseOptions::BufferMap m_assemblies; } - struct Command_Call : CLR_RT_ParseOptions::Command - { - typedef HRESULT (Settings::*FPN)(CLR_RT_ParseOptions::ParameterList *params); - - Settings &m_parent; - FPN m_call; - - Command_Call(Settings &parent, FPN call, const wchar_t *szName, const wchar_t *szDescription) - : CLR_RT_ParseOptions::Command(szName, szDescription), m_parent(parent), m_call(call) - { - } - - virtual HRESULT Execute() - { - return (m_parent.*m_call)(&m_params); - } - }; - -#define PARAM_GENERIC(parm1Name, parm1Desc) \ - param = new CLR_RT_ParseOptions::Parameter_Generic(parm1Name, parm1Desc); \ - cmd->m_params.push_back(param) -#define OPTION_CALL(fpn, optName, optDesc) \ - cmd = new Command_Call(*this, &Settings::fpn, optName, optDesc); \ - m_commands.push_back(cmd) -#define PARAM_EXTRACT_STRING(lst, index) ((CLR_RT_ParseOptions::Parameter_Generic *)(*lst)[index])->m_data.c_str() - HRESULT CheckAssemblyFormat(CLR_RECORD_ASSEMBLY *header, const wchar_t *src) { NANOCLR_HEADER(); @@ -564,7 +520,6 @@ void nanoCLR_SetConfigureCallback(ConfigureRuntimeCallback configureRuntimeCallb void ClrStartup(CLR_SETTINGS params) { NATIVE_PROFILE_CLR_STARTUP(); - // Settings settings; ASSERT(sizeof(CLR_RT_HeapBlock_Raw) == sizeof(struct CLR_RT_HeapBlock)); bool softReboot; diff --git a/targets/netcore/nanoFramework.nanoCLR/nanoCLR_native.cpp b/targets/netcore/nanoFramework.nanoCLR/nanoCLR_native.cpp index d0e10d61c3..52ad8d9df2 100644 --- a/targets/netcore/nanoFramework.nanoCLR/nanoCLR_native.cpp +++ b/targets/netcore/nanoFramework.nanoCLR/nanoCLR_native.cpp @@ -31,9 +31,7 @@ #else -#pragma comment( \ - lib, \ - "WireProtocol.lib") // UNDONE: FIXME: SUPPORT_ComputeCRC required by TypeSystem.cpp, CLR_RT_HeapBlock +#pragma comment(lib, "WireProtocol.lib") #pragma comment(lib, "Debugger_stub.lib") #pragma comment(lib, "Diagnostics_stub.lib") @@ -107,7 +105,7 @@ void nanoCLR_Run(NANO_CLR_SETTINGS nanoClrSettings) BlockStorageList_InitializeDevices(); CLR_SETTINGS clrSettings; - ZeroMemory(&clrSettings, sizeof(clrSettings)); + ZeroMemory(&clrSettings, sizeof(CLR_SETTINGS)); clrSettings.MaxContextSwitches = nanoClrSettings.MaxContextSwitches; clrSettings.WaitForDebugger = nanoClrSettings.WaitForDebugger; diff --git a/targets/win32/Include/Win32TimerQueue.h b/targets/win32/Include/Win32TimerQueue.h index c482329418..a9abd3bdec 100644 --- a/targets/win32/Include/Win32TimerQueue.h +++ b/targets/win32/Include/Win32TimerQueue.h @@ -79,7 +79,9 @@ class Timer { auto err = ::GetLastError(); if (ERROR_IO_PENDING != err) - throw std::exception("Internal error: DeleteTimerQueueTimer() FAILED!", err); + { + CLR_Debug::Printf("Internal error: DeleteTimerQueueTimer() FAILED!\r\n"); + } } } diff --git a/targets/win32/nanoCLR/CLRStartup.cpp b/targets/win32/nanoCLR/CLRStartup.cpp index 30894a66c7..e18910303b 100644 --- a/targets/win32/nanoCLR/CLRStartup.cpp +++ b/targets/win32/nanoCLR/CLRStartup.cpp @@ -19,7 +19,7 @@ struct Settings : CLR_RT_ParseOptions //--// - HRESULT Initialize(CLR_SETTINGS params) + HRESULT Initialize(CLR_SETTINGS const ¶ms) { NANOCLR_HEADER(); @@ -119,8 +119,6 @@ struct Settings : CLR_RT_ParseOptions // clear flag (in case EE wasn't restarted) CLR_EE_DBG_CLR(StateResolutionFailed); - NANOCLR_CHECK_HRESULT(ProcessOptions(m_clrOptions.StartArgs)); - #if !defined(BUILD_RTM) CLR_Debug::Printf("Loading Assemblies.\r\n"); #endif @@ -596,7 +594,6 @@ HRESULT ClrLoadDAT(const wchar_t *szDatFilePath) void ClrStartup(CLR_SETTINGS params) { NATIVE_PROFILE_CLR_STARTUP(); - // Settings settings; ASSERT(sizeof(CLR_RT_HeapBlock_Raw) == sizeof(struct CLR_RT_HeapBlock)); bool softReboot; diff --git a/targets/win32/nanoCLR/Various.cpp b/targets/win32/nanoCLR/Various.cpp index 79ed22021e..3e99ec8f4c 100644 --- a/targets/win32/nanoCLR/Various.cpp +++ b/targets/win32/nanoCLR/Various.cpp @@ -146,7 +146,7 @@ void __cdecl HAL_AddSoftRebootHandler(ON_SOFT_REBOOT_HANDLER handler) bool g_fDoNotUninitializeDebuggerPort = false; -void __cdecl nanoHAL_Initialize(void) +void nanoHAL_Initialize(void) { HAL_CONTINUATION::InitializeList(); HAL_COMPLETION::InitializeList(); @@ -154,15 +154,13 @@ void __cdecl nanoHAL_Initialize(void) Events_Initialize(); } -void __cdecl nanoHAL_Uninitialize(bool isPoweringDown) +void nanoHAL_Uninitialize(bool isPoweringDown) { (void)isPoweringDown; - int i; - // UNDONE: FIXME: CPU_GPIO_Uninitialize(); - for (i = 0; i < ARRAYSIZE(s_rebootHandlers); i++) + for (int i = 0; i < ARRAYSIZE(s_rebootHandlers); i++) { if (s_rebootHandlers[i] != NULL) { diff --git a/targets/win32/nanoCLR/main.cpp b/targets/win32/nanoCLR/main.cpp index 93fa02337c..d9c2245698 100644 --- a/targets/win32/nanoCLR/main.cpp +++ b/targets/win32/nanoCLR/main.cpp @@ -32,9 +32,7 @@ #else -#pragma comment( \ - lib, \ - "WireProtocol.lib") // UNDONE: FIXME: SUPPORT_ComputeCRC required by TypeSystem.cpp, CLR_RT_HeapBlock +#pragma comment(lib, "WireProtocol.lib") #pragma comment(lib, "Debugger_stub.lib") #pragma comment(lib, "Diagnostics_stub.lib") @@ -87,16 +85,6 @@ int _tmain(int argc, _TCHAR *argv[]) clrSettings.WaitForDebugger = false; clrSettings.EnterDebuggerLoopAfterExit = false; - // fill arguments from command line - clrSettings.StartArgs.resize(argc - 1); - - std::wstring_convert> converter; - - for (int i = 0; i < argc - 1; i++) - { - clrSettings.StartArgs[i] = converter.from_bytes(argv[1 + i]); - } - ClrStartup(clrSettings); #if !defined(BUILD_RTM) diff --git a/targets/win32/nanoCLR/targetPAL_Events.cpp b/targets/win32/nanoCLR/targetPAL_Events.cpp index c177697a3a..c5fb7a6aaa 100644 --- a/targets/win32/nanoCLR/targetPAL_Events.cpp +++ b/targets/win32/nanoCLR/targetPAL_Events.cpp @@ -6,9 +6,10 @@ #include "stdafx.h" #include +#include -static std::unique_ptr boolEventsTimer; -static bool *saveTimerCompleteFlag = 0; +static std::unique_ptr boolEventsTimer = nullptr; +static bool *saveTimerCompleteFlag = nullptr; void local_Events_SetBoolTimer_Callback() { @@ -19,7 +20,7 @@ void local_Events_SetBoolTimer_Callback() bool Events_Initialize_Platform() { - boolEventsTimer = NULL; + boolEventsTimer = nullptr; return true; } @@ -29,9 +30,9 @@ void Events_SetBoolTimer(bool *timerCompleteFlag, uint32_t millisecondsFromNow) NATIVE_PROFILE_PAL_EVENTS(); // we assume only 1 can be active, abort previous just in case - if (boolEventsTimer != NULL) + if (boolEventsTimer != nullptr) { - delete boolEventsTimer.release(); + boolEventsTimer.reset(); } if (timerCompleteFlag) @@ -44,48 +45,66 @@ void Events_SetBoolTimer(bool *timerCompleteFlag, uint32_t millisecondsFromNow) } } -// mutex, condition variable and flags for CLR's global events state -static std::mutex EventsMutex; +// semaphore, condition variable and flags for CLR's global events state +static std::binary_semaphore EventsSemaphore(1); static std::condition_variable EventsConditionVar; static uint32_t SystemEvents; bool Events_Initialize() { - std::unique_lock scopeLock(EventsMutex); + Events_Initialize_Platform(); + + EventsSemaphore.acquire(); + SystemEvents = 0; + + EventsSemaphore.release(); + return TRUE; } bool Events_Uninitialize() { - std::unique_lock scopeLock(EventsMutex); + EventsSemaphore.acquire(); + SystemEvents = 0; + + EventsSemaphore.release(); + return TRUE; } void Events_Set(UINT32 Events) { - { - std::unique_lock scopeLock(EventsMutex); - SystemEvents |= Events; - } + EventsSemaphore.acquire(); + + SystemEvents |= Events; + + EventsSemaphore.release(); + EventsConditionVar.notify_all(); } uint32_t Events_Get(UINT32 EventsOfInterest) { - std::unique_lock scopeLock(EventsMutex); + EventsSemaphore.acquire(); + auto retVal = SystemEvents & EventsOfInterest; SystemEvents &= ~EventsOfInterest; + + EventsSemaphore.release(); + return retVal; } void Events_Clear(UINT32 Events) { - { - std::unique_lock scopeLock(EventsMutex); - SystemEvents &= ~Events; - } + EventsSemaphore.acquire(); + + SystemEvents &= ~Events; + + EventsSemaphore.release(); + EventsConditionVar.notify_all(); } @@ -97,22 +116,36 @@ uint32_t Events_MaskedRead(uint32_t Events) // block this thread and wake up when at least one of the requested events is set or a timeout occurs... uint32_t Events_WaitForEvents(uint32_t powerLevel, uint32_t wakeupSystemEvents, uint32_t timeoutMilliseconds) { - std::unique_lock scopeLock(EventsMutex); - - if (CLR_EE_DBG_IS(RebootPending) || CLR_EE_DBG_IS(ExitPending)) - { - // there is a reboot or program exit condition pending, no need to wait for anything - return 0; - } + (void)powerLevel; // Assuming powerLevel is not used in this context + auto startTime = std::chrono::steady_clock::now(); + auto endTime = startTime + std::chrono::milliseconds(timeoutMilliseconds); bool timeout = false; - // check current condition before waiting as Condition var doesn't do that - if ((wakeupSystemEvents & SystemEvents) == 0) + while (true) { - timeout = !EventsConditionVar.wait_for(scopeLock, std::chrono::milliseconds(timeoutMilliseconds), [=]() { - return (wakeupSystemEvents & SystemEvents) != 0; - }); + // Attempt to acquire the semaphore with a short wait to poll the condition + if (EventsSemaphore.try_acquire_for(std::chrono::milliseconds(10))) + { + if (CLR_EE_DBG_IS(RebootPending) || CLR_EE_DBG_IS(ExitPending) || (wakeupSystemEvents & SystemEvents) != 0) + { + // Condition met or special case encountered, break the loop + // Release the semaphore before breaking + EventsSemaphore.release(); + break; + } + + // Release the semaphore if condition not met + EventsSemaphore.release(); + } + + if (std::chrono::steady_clock::now() >= endTime) + { + timeout = true; + + // Exit the loop if timeout reached + break; + } } return timeout ? 0 : SystemEvents & wakeupSystemEvents; @@ -120,9 +153,18 @@ uint32_t Events_WaitForEvents(uint32_t powerLevel, uint32_t wakeupSystemEvents, void Events_SetCallback(set_Event_Callback pfn, void *arg) { + (void)pfn; + (void)arg; + _ASSERTE(FALSE); } void FreeManagedEvent(uint8_t category, uint8_t subCategory, uint16_t data1, uint32_t data2) { + (void)category; + (void)subCategory; + (void)data1; + (void)data2; + + // nothing to release in this platform }