Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix mutex in PAL Events for virtual nanoCLR #2957

Merged
merged 32 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
25cac19
Testing virtual nanoCLR on pipeline
josesimoes Jun 11, 2024
e354851
Remove StartArgs from CLR_SETTINGS struct
josesimoes Jun 11, 2024
ecc0b93
Fix tasks to grab vstest crash dumps
josesimoes Jun 11, 2024
b22b87d
Remove unused code
josesimoes Jun 11, 2024
6633aa4
Fix filter
josesimoes Jun 11, 2024
7dab551
Experimenting code changes
josesimoes Jun 11, 2024
3302055
Adjust yaml to publish dump files only if they exist
josesimoes Jun 11, 2024
2d9c423
Add docker file for Windows Server 2022
josesimoes Jun 11, 2024
e28c526
More code changes for testing
josesimoes Jun 11, 2024
95a76e1
Fix docker stuff
josesimoes Jun 11, 2024
f3f77cd
Testing more startup code
josesimoes Jun 11, 2024
ef475f4
Adjust windows server container
josesimoes Jun 11, 2024
626fc44
More startup code tests
josesimoes Jun 11, 2024
70ab0c9
More code tests
josesimoes Jun 11, 2024
7c929f5
More code tests
josesimoes Jun 11, 2024
9cdeb7f
More code test
josesimoes Jun 11, 2024
2051da8
More code testing
josesimoes Jun 11, 2024
e09dd29
More code testing
josesimoes Jun 11, 2024
c3e145a
Fix filter in copy filters
josesimoes Jun 11, 2024
dbb37a4
Remove windows server dev container
josesimoes Jun 11, 2024
4660223
Uncomment back yaml sections
josesimoes Jun 11, 2024
0ad8ea7
Code style fixes for nanoframework/nf-interpreter PR#2957 (#2958)
nfbot Jun 11, 2024
7491aad
Code style fixes for nanoframework/nf-interpreter PR#2957 (#2959)
nfbot Jun 11, 2024
1c99e9d
Remove outdated comment
josesimoes Jun 11, 2024
35162a9
Add back comment yaml
josesimoes Jun 12, 2024
a356578
Testing with events code
josesimoes Jun 12, 2024
c1e08f0
Replace mutex with binary semaphore
josesimoes Jun 12, 2024
f3dce56
Uncomment yaml
josesimoes Jun 12, 2024
df833b1
Replace mutex with semaphore
josesimoes Jun 12, 2024
c4c5202
Fix PS1 checking for dump files
josesimoes Jun 12, 2024
b3a5f3a
Remove outdated comment
josesimoes Jun 12, 2024
0498f53
Fix AZDO job
josesimoes Jun 12, 2024
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
932 changes: 466 additions & 466 deletions azure-pipelines-nightly.yml

Large diffs are not rendered by default.

1,268 changes: 645 additions & 623 deletions azure-pipelines.yml

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions src/CLR/Core/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@

#include <nanoCLR_Runtime.h>
#include <nanoCLR_Checks.h>
//#include <nanoCLR_Diagnostics.h>
// #include <nanoCLR_Diagnostics.h>
#include <nanoCLR_Hardware.h>
//#include <nanoCLR_Stream.h>
//#include <nanoCLR_Xml.h>
//#include <nanoCLR_Application.h>
// #include <nanoCLR_Stream.h>
josesimoes marked this conversation as resolved.
Show resolved Hide resolved
// #include <nanoCLR_Xml.h>
#include <nanoCLR_Application.h>
josesimoes marked this conversation as resolved.
Show resolved Hide resolved
//
//#include <nanoCLR_ParseOptions.h>
// #include <nanoCLR_ParseOptions.h>
//
#include <corlib_native.h>
//#include <SPOT_native.h>
//#include <SPOT_hardware_native.h>
// #include <SPOT_native.h>
// #include <SPOT_hardware_native.h>
#include <nanoCLR_Runtime__HeapBlock.h>

#endif // NANOCLR_CORE_H
1 change: 0 additions & 1 deletion src/CLR/Include/nanoCLR_Application.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ typedef struct CLR_SETTINGS
#if defined(VIRTUAL_DEVICE)
bool PerformGarbageCollection;
bool PerformHeapCompaction;
CLR_RT_StringVector StartArgs;
#endif

} CLR_SETTINGS;
Expand Down
47 changes: 1 addition & 46 deletions targets/netcore/nanoFramework.nanoCLR/CLRStartup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,30 +24,12 @@ struct Settings

//--//

HRESULT Initialize(CLR_SETTINGS params)
HRESULT Initialize(CLR_SETTINGS const &params)
{
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");
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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;

Expand Down
6 changes: 2 additions & 4 deletions targets/netcore/nanoFramework.nanoCLR/nanoCLR_native.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 3 additions & 1 deletion targets/win32/Include/Win32TimerQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
}
}

Expand Down
5 changes: 1 addition & 4 deletions targets/win32/nanoCLR/CLRStartup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct Settings : CLR_RT_ParseOptions

//--//

HRESULT Initialize(CLR_SETTINGS params)
HRESULT Initialize(CLR_SETTINGS const &params)
josesimoes marked this conversation as resolved.
Show resolved Hide resolved
{
NANOCLR_HEADER();

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;

Expand Down
8 changes: 3 additions & 5 deletions targets/win32/nanoCLR/Various.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,23 +146,21 @@ 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();

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++)
josesimoes marked this conversation as resolved.
Show resolved Hide resolved
{
if (s_rebootHandlers[i] != NULL)
{
Expand Down
10 changes: 0 additions & 10 deletions targets/win32/nanoCLR/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,16 +87,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<std::codecvt_utf8_utf16<wchar_t>> converter;

for (int i = 0; i < argc - 1; i++)
{
clrSettings.StartArgs[i] = converter.from_bytes(argv[1 + i]);
}

ClrStartup(clrSettings);

#if !defined(BUILD_RTM)
Expand Down
98 changes: 70 additions & 28 deletions targets/win32/nanoCLR/targetPAL_Events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@

#include "stdafx.h"
#include <Win32TimerQueue.h>
#include <semaphore>

static std::unique_ptr<Microsoft::Win32::Timer> boolEventsTimer;
static bool *saveTimerCompleteFlag = 0;
static std::unique_ptr<Microsoft::Win32::Timer> boolEventsTimer = nullptr;
static bool *saveTimerCompleteFlag = nullptr;

void local_Events_SetBoolTimer_Callback()
{
Expand All @@ -19,7 +20,7 @@ void local_Events_SetBoolTimer_Callback()

bool Events_Initialize_Platform()
{
boolEventsTimer = NULL;
boolEventsTimer = nullptr;

return true;
}
Expand All @@ -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)
Expand All @@ -45,47 +46,65 @@ void Events_SetBoolTimer(bool *timerCompleteFlag, uint32_t millisecondsFromNow)
}

// mutex, condition variable and flags for CLR's global events state
static std::mutex EventsMutex;
static std::binary_semaphore EventsSemaphore(1);
static std::condition_variable EventsConditionVar;
static uint32_t SystemEvents;

bool Events_Initialize()
{
std::unique_lock<std::mutex> scopeLock(EventsMutex);
Events_Initialize_Platform();

EventsSemaphore.acquire();

SystemEvents = 0;

EventsSemaphore.release();

return TRUE;
}

bool Events_Uninitialize()
{
std::unique_lock<std::mutex> scopeLock(EventsMutex);
SystemEvents = 0;
EventsSemaphore.acquire();

SystemEvents = 0;

EventsSemaphore.release();

return TRUE;
}

void Events_Set(UINT32 Events)
{
{
std::unique_lock<std::mutex> scopeLock(EventsMutex);
EventsSemaphore.acquire();

SystemEvents |= Events;
}

EventsSemaphore.release();

EventsConditionVar.notify_all();
}

uint32_t Events_Get(UINT32 EventsOfInterest)
{
std::unique_lock<std::mutex> scopeLock(EventsMutex);
EventsSemaphore.acquire();

auto retVal = SystemEvents & EventsOfInterest;
SystemEvents &= ~EventsOfInterest;

EventsSemaphore.release();

return retVal;
}

void Events_Clear(UINT32 Events)
{
{
std::unique_lock<std::mutex> scopeLock(EventsMutex);
EventsSemaphore.acquire();

SystemEvents &= ~Events;
}

EventsSemaphore.release();

EventsConditionVar.notify_all();
}

Expand All @@ -97,32 +116,55 @@ 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<std::mutex> 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;
}

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
}
Loading