diff --git a/projects/clr/rocclr/device/devhostcall.cpp b/projects/clr/rocclr/device/devhostcall.cpp index a73c4451b9..c49ecc0126 100644 --- a/projects/clr/rocclr/device/devhostcall.cpp +++ b/projects/clr/rocclr/device/devhostcall.cpp @@ -335,10 +335,10 @@ void HostcallListener::removeBuffer(HostcallBuffer* buffer) { bool HostcallListener::initialize(const amd::Device &dev) { doorbell_ = dev.createSignal(); -#ifdef WITH_HSA_DEVICE - auto ws = device::Signal::WaitState::Blocked; -#else +#if defined(WITH_PAL_DEVICE) && !defined(_WIN32) auto ws = device::Signal::WaitState::Active; +#else + auto ws = device::Signal::WaitState::Blocked; #endif if ((doorbell_ == nullptr) || !doorbell_->Init(dev, SIGNAL_INIT, ws)) { return false; diff --git a/projects/clr/rocclr/device/pal/palsignal.cpp b/projects/clr/rocclr/device/pal/palsignal.cpp index 4f7ac33ccf..0764647419 100644 --- a/projects/clr/rocclr/device/pal/palsignal.cpp +++ b/projects/clr/rocclr/device/pal/palsignal.cpp @@ -29,6 +29,21 @@ namespace pal { Signal::~Signal() { dev_->context().svmFree(amdSignal_); + + if (ws_ == device::Signal::WaitState::Blocked) { +#if defined(_WIN32) + Pal::Result result = Pal::Result::Success; + + Pal::UnregisterEventInfo eventInfo = {}; + eventInfo.pEvent = &event_; + eventInfo.trackingType = Pal::EventTrackingType::ShaderInterrupt; + result = dev_->iDev()->UnregisterEvent(eventInfo); + if (result != Pal::Result::Success) { + ClPrint(amd::LOG_ERROR, amd::LOG_QUEUE, + "Failed to unregister SQ event needed for hostcall buffer"); + } +#endif + } } bool Signal::Init(const amd::Device& dev, uint64_t init, device::Signal::WaitState ws) { @@ -47,6 +62,47 @@ bool Signal::Init(const amd::Device& dev, uint64_t init, device::Signal::WaitSta amdSignal_ = new (buffer) amd_signal_t(); amdSignal_->value = init; + if (ws_ == device::Signal::WaitState::Blocked) { +#if defined(_WIN32) + Pal::Result result = Pal::Result::Success; + + Util::EventCreateFlags flags = {}; + flags.manualReset = false; + flags.initiallySignaled = false; + result = event_.Init(flags); + if (result != Pal::Result::Success) { + ClPrint(amd::LOG_ERROR, amd::LOG_QUEUE, + "Failed to create Pal::Util::Event needed for hostcall buffer"); + return false; + } + + result = event_.Set(); + if (result != Pal::Result::Success) { + ClPrint(amd::LOG_ERROR, amd::LOG_QUEUE, + "Failed to set Pal::Util::Event needed for hostcall buffer"); + return false; + } + + Pal::RegisterEventInfo eventInputInfo = {}; + eventInputInfo.pEvent = &event_; + eventInputInfo.trackingType = Pal::EventTrackingType::ShaderInterrupt; + Pal::RegisterEventOutputInfo eventOutputInfo = {}; + result = dev_->iDev()->RegisterEvent( + eventInputInfo, + &eventOutputInfo); + if (result != Pal::Result::Success) { + ClPrint(amd::LOG_ERROR, amd::LOG_QUEUE, + "Failed to register SQ event needed for hostcall buffer"); + return false; + } + amdSignal_->event_id = eventOutputInfo.shaderInterrupt.eventId; + amdSignal_->event_mailbox_ptr = eventOutputInfo.shaderInterrupt.eventMailboxGpuVa; + ClPrint(amd::LOG_INFO, amd::LOG_INIT, + "Registered SQ event %d with mailbox slot %p", + amdSignal_->event_id, amdSignal_->event_mailbox_ptr); +#endif + } + return true; } @@ -67,7 +123,19 @@ uint64_t Signal::Wait(uint64_t value, device::Signal::Condition c, uint64_t time } (c); if (ws_ == device::Signal::WaitState::Blocked) { - guarantee(false, "Unimplemented"); +#if defined(_WIN32) + Pal::Result result = Pal::Result::Success; + + float timeoutInSec = timeout / (1000 * 1000); + result = event_.Wait(timeoutInSec); + + if (result != Pal::Result::Success) { + return -1; + } + + std::atomic_thread_fence(std::memory_order_acquire); + return amdSignal_->value; +#endif } else if (ws_ == device::Signal::WaitState::Active) { auto start = amd::Os::timeNanos(); while (true) { diff --git a/projects/clr/rocclr/device/pal/palsignal.hpp b/projects/clr/rocclr/device/pal/palsignal.hpp index d043c6a921..781cbd6b1f 100644 --- a/projects/clr/rocclr/device/pal/palsignal.hpp +++ b/projects/clr/rocclr/device/pal/palsignal.hpp @@ -24,6 +24,8 @@ #include +#include "palEvent.h" + namespace pal { class Device; @@ -32,6 +34,7 @@ class Signal: public device::Signal { private: const Device* dev_; amd_signal_t* amdSignal_; + Util::Event event_; public: ~Signal() override;