Skip to content

Commit 878466a

Browse files
Correct infinite timeout argument for event synchronization
Related-To: NEO-6242 Signed-off-by: Zbigniew Zdanowicz <[email protected]>
1 parent 493b01e commit 878466a

File tree

4 files changed

+99
-17
lines changed

4 files changed

+99
-17
lines changed

level_zero/core/source/event/event_impl.inl

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,11 @@ ze_result_t EventImp<TagSizeT>::queryStatusKernelTimestamp() {
100100
for (uint32_t i = 0; i < kernelCount; i++) {
101101
uint32_t packetsToCheck = kernelEventCompletionData[i].getPacketsUsed();
102102
for (uint32_t packetId = 0; packetId < packetsToCheck; packetId++) {
103-
if (kernelEventCompletionData[i].getContextEndValue(packetId) == queryVal) {
103+
bool notReady = NEO::WaitUtils::waitFunctionWithPredicate<const TagSizeT>(
104+
static_cast<TagSizeT const *>(kernelEventCompletionData[i].getContextEndAddress(packetId)),
105+
queryVal,
106+
std::equal_to<TagSizeT>());
107+
if (notReady) {
104108
return ZE_RESULT_NOT_READY;
105109
}
106110
}
@@ -116,7 +120,11 @@ ze_result_t EventImp<TagSizeT>::queryStatusNonTimestamp() {
116120
for (uint32_t i = 0; i < kernelCount; i++) {
117121
uint32_t packetsToCheck = kernelEventCompletionData[i].getPacketsUsed();
118122
for (uint32_t packetId = 0; packetId < packetsToCheck; packetId++) {
119-
if (kernelEventCompletionData[i].getContextStartValue(packetId) == queryVal) {
123+
bool notReady = NEO::WaitUtils::waitFunctionWithPredicate<const TagSizeT>(
124+
static_cast<TagSizeT const *>(kernelEventCompletionData[i].getContextStartAddress(packetId)),
125+
queryVal,
126+
std::equal_to<TagSizeT>());
127+
if (notReady) {
120128
return ZE_RESULT_NOT_READY;
121129
}
122130
}
@@ -221,8 +229,6 @@ ze_result_t EventImp<TagSizeT>::hostSynchronize(uint64_t timeout) {
221229
return ret;
222230
}
223231

224-
NEO::WaitUtils::waitFunction(nullptr, 0u);
225-
226232
currentTime = std::chrono::high_resolution_clock::now();
227233
elapsedTimeSinceGpuHangCheck = std::chrono::duration_cast<std::chrono::microseconds>(currentTime - lastHangCheckTime);
228234

@@ -233,7 +239,7 @@ ze_result_t EventImp<TagSizeT>::hostSynchronize(uint64_t timeout) {
233239
}
234240
}
235241

236-
if (timeout == std::numeric_limits<uint32_t>::max()) {
242+
if (timeout == std::numeric_limits<uint64_t>::max()) {
237243
continue;
238244
}
239245

level_zero/core/test/unit_tests/sources/event/test_event.cpp

Lines changed: 85 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
#include "shared/test/common/helpers/debug_manager_state_restore.h"
9+
#include "shared/test/common/helpers/variable_backup.h"
910
#include "shared/test/common/mocks/mock_compilers.h"
1011
#include "shared/test/common/mocks/mock_csr.h"
1112
#include "shared/test/common/mocks/mock_memory_manager.h"
@@ -29,8 +30,11 @@
2930
using namespace std::chrono_literals;
3031

3132
namespace CpuIntrinsicsTests {
32-
extern std::atomic<uintptr_t> lastClFlushedPtr;
33-
extern std::atomic<uint32_t> clFlushCounter;
33+
extern std::atomic<uint32_t> pauseCounter;
34+
extern volatile uint32_t *pauseAddress;
35+
extern uint32_t pauseValue;
36+
extern uint32_t pauseOffset;
37+
extern std::function<void()> setupPauseAddress;
3438
} // namespace CpuIntrinsicsTests
3539

3640
namespace L0 {
@@ -627,8 +631,8 @@ TEST_F(EventSynchronizeTest, GivenGpuHangWhenHostSynchronizeIsCalledThenDeviceLo
627631
event->csr = csr.get();
628632
event->gpuHangCheckPeriod = 0ms;
629633

630-
const auto timeout = std::numeric_limits<std::uint32_t>::max();
631-
const auto result = event->hostSynchronize(timeout);
634+
constexpr uint64_t timeout = std::numeric_limits<std::uint64_t>::max();
635+
auto result = event->hostSynchronize(timeout);
632636

633637
EXPECT_EQ(ZE_RESULT_ERROR_DEVICE_LOST, result);
634638
}
@@ -640,8 +644,8 @@ TEST_F(EventSynchronizeTest, GivenNoGpuHangAndOneNanosecondTimeoutWhenHostSynchr
640644
event->csr = csr.get();
641645
event->gpuHangCheckPeriod = 0ms;
642646

643-
const auto timeoutNanoseconds = 1;
644-
const auto result = event->hostSynchronize(timeoutNanoseconds);
647+
constexpr uint64_t timeoutNanoseconds = 1;
648+
auto result = event->hostSynchronize(timeoutNanoseconds);
645649

646650
EXPECT_EQ(ZE_RESULT_NOT_READY, result);
647651
}
@@ -651,8 +655,8 @@ TEST_F(EventSynchronizeTest, GivenLongPeriodOfGpuCheckAndOneNanosecondTimeoutWhe
651655
event->csr = csr.get();
652656
event->gpuHangCheckPeriod = 50000000ms;
653657

654-
const auto timeoutNanoseconds = 1;
655-
const auto result = event->hostSynchronize(timeoutNanoseconds);
658+
constexpr uint64_t timeoutNanoseconds = 1;
659+
auto result = event->hostSynchronize(timeoutNanoseconds);
656660

657661
EXPECT_EQ(ZE_RESULT_NOT_READY, result);
658662
}
@@ -668,19 +672,90 @@ TEST_F(EventSynchronizeTest, givenCallToEventHostSynchronizeWithNonZeroTimeoutAn
668672
}
669673

670674
TEST_F(EventSynchronizeTest, givenCallToEventHostSynchronizeWithTimeoutZeroAndStateSignaledHostSynchronizeReturnsSuccess) {
671-
uint64_t *hostAddr = static_cast<uint64_t *>(event->getHostAddress());
675+
uint32_t *hostAddr = static_cast<uint32_t *>(event->getHostAddress());
672676
*hostAddr = Event::STATE_SIGNALED;
673677
ze_result_t result = event->hostSynchronize(0);
674678
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
675679
}
676680

677681
TEST_F(EventSynchronizeTest, givenCallToEventHostSynchronizeWithTimeoutNonZeroAndStateSignaledHostSynchronizeReturnsSuccess) {
678-
uint64_t *hostAddr = static_cast<uint64_t *>(event->getHostAddress());
682+
uint32_t *hostAddr = static_cast<uint32_t *>(event->getHostAddress());
679683
*hostAddr = Event::STATE_SIGNALED;
680684
ze_result_t result = event->hostSynchronize(10);
681685
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
682686
}
683687

688+
TEST_F(EventSynchronizeTest, givenInfiniteTimeoutWhenWaitingForNonTimestampEventCompletionThenReturnOnlyAfterAllEventPacketsAreCompleted) {
689+
constexpr uint32_t packetsInUse = 2;
690+
event->setPacketsInUse(packetsInUse);
691+
692+
const size_t eventPacketSize = event->getSinglePacketSize();
693+
const size_t eventCompletionOffset = event->getContextStartOffset();
694+
695+
VariableBackup<volatile uint32_t *> backupPauseAddress(&CpuIntrinsicsTests::pauseAddress);
696+
VariableBackup<uint32_t> backupPauseValue(&CpuIntrinsicsTests::pauseValue, Event::STATE_CLEARED);
697+
VariableBackup<uint32_t> backupPauseOffset(&CpuIntrinsicsTests::pauseOffset);
698+
VariableBackup<std::function<void()>> backupSetupPauseAddress(&CpuIntrinsicsTests::setupPauseAddress);
699+
CpuIntrinsicsTests::pauseCounter = 0u;
700+
CpuIntrinsicsTests::pauseAddress = static_cast<uint32_t *>(ptrOffset(event->getHostAddress(), eventCompletionOffset));
701+
702+
uint32_t *hostAddr = static_cast<uint32_t *>(ptrOffset(event->getHostAddress(), eventCompletionOffset));
703+
for (uint32_t i = 0; i < packetsInUse; i++) {
704+
*hostAddr = Event::STATE_CLEARED;
705+
hostAddr = ptrOffset(hostAddr, eventPacketSize);
706+
}
707+
708+
CpuIntrinsicsTests::setupPauseAddress = [&]() {
709+
if (CpuIntrinsicsTests::pauseCounter > 10) {
710+
volatile uint32_t *nextPacket = CpuIntrinsicsTests::pauseAddress;
711+
for (uint32_t i = 0; i < packetsInUse; i++) {
712+
*nextPacket = Event::STATE_SIGNALED;
713+
nextPacket = ptrOffset(nextPacket, eventPacketSize);
714+
}
715+
}
716+
};
717+
718+
constexpr uint64_t infiniteTimeout = std::numeric_limits<std::uint64_t>::max();
719+
ze_result_t result = event->hostSynchronize(infiniteTimeout);
720+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
721+
}
722+
723+
TEST_F(EventSynchronizeTest, givenInfiniteTimeoutWhenWaitingForTimestampEventCompletionThenReturnOnlyAfterAllEventPacketsAreCompleted) {
724+
constexpr uint32_t packetsInUse = 2;
725+
event->setPacketsInUse(packetsInUse);
726+
event->setEventTimestampFlag(true);
727+
728+
const size_t eventPacketSize = event->getSinglePacketSize();
729+
const size_t eventCompletionOffset = event->getContextEndOffset();
730+
731+
VariableBackup<volatile uint32_t *> backupPauseAddress(&CpuIntrinsicsTests::pauseAddress);
732+
VariableBackup<uint32_t> backupPauseValue(&CpuIntrinsicsTests::pauseValue, Event::STATE_CLEARED);
733+
VariableBackup<uint32_t> backupPauseOffset(&CpuIntrinsicsTests::pauseOffset);
734+
VariableBackup<std::function<void()>> backupSetupPauseAddress(&CpuIntrinsicsTests::setupPauseAddress);
735+
CpuIntrinsicsTests::pauseCounter = 0u;
736+
CpuIntrinsicsTests::pauseAddress = static_cast<uint32_t *>(ptrOffset(event->getHostAddress(), eventCompletionOffset));
737+
738+
uint32_t *hostAddr = static_cast<uint32_t *>(ptrOffset(event->getHostAddress(), eventCompletionOffset));
739+
for (uint32_t i = 0; i < packetsInUse; i++) {
740+
*hostAddr = Event::STATE_CLEARED;
741+
hostAddr = ptrOffset(hostAddr, eventPacketSize);
742+
}
743+
744+
CpuIntrinsicsTests::setupPauseAddress = [&]() {
745+
if (CpuIntrinsicsTests::pauseCounter > 10) {
746+
volatile uint32_t *nextPacket = CpuIntrinsicsTests::pauseAddress;
747+
for (uint32_t i = 0; i < packetsInUse; i++) {
748+
*nextPacket = Event::STATE_SIGNALED;
749+
nextPacket = ptrOffset(nextPacket, eventPacketSize);
750+
}
751+
}
752+
};
753+
754+
constexpr uint64_t infiniteTimeout = std::numeric_limits<std::uint64_t>::max();
755+
ze_result_t result = event->hostSynchronize(infiniteTimeout);
756+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
757+
}
758+
684759
using EventPoolIPCEventResetTests = Test<DeviceFixture>;
685760

686761
TEST_F(EventPoolIPCEventResetTests, whenOpeningIpcHandleForEventPoolCreateWithIpcFlagThenEventsInNewPoolAreNotReset) {

level_zero/core/test/unit_tests/sources/fence/test_fence.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ TEST_F(FenceTest, GivenGpuHangWhenHostSynchronizeIsCalledThenDeviceLostIsReturne
7171
fence->taskCount = 1;
7272
fence->gpuHangCheckPeriod = 0ms;
7373

74-
const auto timeout = std::numeric_limits<std::uint32_t>::max();
74+
const auto timeout = std::numeric_limits<std::uint64_t>::max();
7575
const auto result = fence->hostSynchronize(timeout);
7676

7777
EXPECT_EQ(ZE_RESULT_ERROR_DEVICE_LOST, result);
@@ -131,7 +131,7 @@ TEST_F(FenceTest, GivenSuccessfulQueryResultAndNoTimeoutWhenHostSynchronizeIsCal
131131

132132
fence->taskCount = 1;
133133

134-
const auto timeout = std::numeric_limits<std::uint32_t>::max();
134+
const auto timeout = std::numeric_limits<std::uint64_t>::max();
135135
const auto result = fence->hostSynchronize(timeout);
136136

137137
EXPECT_EQ(ZE_RESULT_SUCCESS, result);

shared/source/helpers/timestamp_packet.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class TimestampPackets : public TagTypeBase {
7171
uint64_t getGlobalEndValue(uint32_t packetIndex) const { return static_cast<uint64_t>(packets[packetIndex].globalEnd); }
7272

7373
void const *getContextEndAddress(uint32_t packetIndex) const { return static_cast<void const *>(&packets[packetIndex].contextEnd); }
74+
void const *getContextStartAddress(uint32_t packetIndex) const { return static_cast<void const *>(&packets[packetIndex].contextStart); }
7475

7576
protected:
7677
Packet packets[TimestampPacketSizeControl::preferredPacketCount];

0 commit comments

Comments
 (0)