Correct infinite timeout argument for event synchronization

Related-To: NEO-6242

Signed-off-by: Zbigniew Zdanowicz <zbigniew.zdanowicz@intel.com>
This commit is contained in:
Zbigniew Zdanowicz 2022-03-17 18:44:34 +00:00 committed by Compute-Runtime-Automation
parent a968cb223e
commit 1540d06c25
4 changed files with 105 additions and 23 deletions

View File

@ -100,7 +100,11 @@ ze_result_t EventImp<TagSizeT>::queryStatusKernelTimestamp() {
for (uint32_t i = 0; i < kernelCount; i++) {
uint32_t packetsToCheck = kernelEventCompletionData[i].getPacketsUsed();
for (uint32_t packetId = 0; packetId < packetsToCheck; packetId++) {
if (kernelEventCompletionData[i].getContextEndValue(packetId) == queryVal) {
bool ready = NEO::WaitUtils::waitFunctionWithPredicate<const TagSizeT>(
static_cast<TagSizeT const *>(kernelEventCompletionData[i].getContextEndAddress(packetId)),
queryVal,
std::not_equal_to<TagSizeT>());
if (!ready) {
return ZE_RESULT_NOT_READY;
}
}
@ -116,7 +120,11 @@ ze_result_t EventImp<TagSizeT>::queryStatusNonTimestamp() {
for (uint32_t i = 0; i < kernelCount; i++) {
uint32_t packetsToCheck = kernelEventCompletionData[i].getPacketsUsed();
for (uint32_t packetId = 0; packetId < packetsToCheck; packetId++) {
if (kernelEventCompletionData[i].getContextStartValue(packetId) == queryVal) {
bool ready = NEO::WaitUtils::waitFunctionWithPredicate<const TagSizeT>(
static_cast<TagSizeT const *>(kernelEventCompletionData[i].getContextStartAddress(packetId)),
queryVal,
std::not_equal_to<TagSizeT>());
if (!ready) {
return ZE_RESULT_NOT_READY;
}
}
@ -221,8 +229,6 @@ ze_result_t EventImp<TagSizeT>::hostSynchronize(uint64_t timeout) {
return ret;
}
NEO::WaitUtils::waitFunction(nullptr, 0u);
currentTime = std::chrono::high_resolution_clock::now();
elapsedTimeSinceGpuHangCheck = std::chrono::duration_cast<std::chrono::microseconds>(currentTime - lastHangCheckTime);
@ -233,7 +239,7 @@ ze_result_t EventImp<TagSizeT>::hostSynchronize(uint64_t timeout) {
}
}
if (timeout == std::numeric_limits<uint32_t>::max()) {
if (timeout == std::numeric_limits<uint64_t>::max()) {
continue;
}

View File

@ -6,6 +6,7 @@
*/
#include "shared/test/common/helpers/debug_manager_state_restore.h"
#include "shared/test/common/helpers/variable_backup.h"
#include "shared/test/common/mocks/mock_compilers.h"
#include "shared/test/common/mocks/mock_csr.h"
#include "shared/test/common/mocks/mock_memory_manager.h"
@ -29,8 +30,11 @@
using namespace std::chrono_literals;
namespace CpuIntrinsicsTests {
extern std::atomic<uintptr_t> lastClFlushedPtr;
extern std::atomic<uint32_t> clFlushCounter;
extern std::atomic<uint32_t> pauseCounter;
extern volatile uint32_t *pauseAddress;
extern uint32_t pauseValue;
extern uint32_t pauseOffset;
extern std::function<void()> setupPauseAddress;
} // namespace CpuIntrinsicsTests
namespace L0 {
@ -627,8 +631,8 @@ TEST_F(EventSynchronizeTest, GivenGpuHangWhenHostSynchronizeIsCalledThenDeviceLo
event->csr = csr.get();
event->gpuHangCheckPeriod = 0ms;
const auto timeout = std::numeric_limits<std::uint32_t>::max();
const auto result = event->hostSynchronize(timeout);
constexpr uint64_t timeout = std::numeric_limits<std::uint64_t>::max();
auto result = event->hostSynchronize(timeout);
EXPECT_EQ(ZE_RESULT_ERROR_DEVICE_LOST, result);
}
@ -640,8 +644,8 @@ TEST_F(EventSynchronizeTest, GivenNoGpuHangAndOneNanosecondTimeoutWhenHostSynchr
event->csr = csr.get();
event->gpuHangCheckPeriod = 0ms;
const auto timeoutNanoseconds = 1;
const auto result = event->hostSynchronize(timeoutNanoseconds);
constexpr uint64_t timeoutNanoseconds = 1;
auto result = event->hostSynchronize(timeoutNanoseconds);
EXPECT_EQ(ZE_RESULT_NOT_READY, result);
}
@ -651,8 +655,8 @@ TEST_F(EventSynchronizeTest, GivenLongPeriodOfGpuCheckAndOneNanosecondTimeoutWhe
event->csr = csr.get();
event->gpuHangCheckPeriod = 50000000ms;
const auto timeoutNanoseconds = 1;
const auto result = event->hostSynchronize(timeoutNanoseconds);
constexpr uint64_t timeoutNanoseconds = 1;
auto result = event->hostSynchronize(timeoutNanoseconds);
EXPECT_EQ(ZE_RESULT_NOT_READY, result);
}
@ -668,19 +672,90 @@ TEST_F(EventSynchronizeTest, givenCallToEventHostSynchronizeWithNonZeroTimeoutAn
}
TEST_F(EventSynchronizeTest, givenCallToEventHostSynchronizeWithTimeoutZeroAndStateSignaledHostSynchronizeReturnsSuccess) {
uint64_t *hostAddr = static_cast<uint64_t *>(event->getHostAddress());
uint32_t *hostAddr = static_cast<uint32_t *>(event->getHostAddress());
*hostAddr = Event::STATE_SIGNALED;
ze_result_t result = event->hostSynchronize(0);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(EventSynchronizeTest, givenCallToEventHostSynchronizeWithTimeoutNonZeroAndStateSignaledHostSynchronizeReturnsSuccess) {
uint64_t *hostAddr = static_cast<uint64_t *>(event->getHostAddress());
uint32_t *hostAddr = static_cast<uint32_t *>(event->getHostAddress());
*hostAddr = Event::STATE_SIGNALED;
ze_result_t result = event->hostSynchronize(10);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(EventSynchronizeTest, givenInfiniteTimeoutWhenWaitingForNonTimestampEventCompletionThenReturnOnlyAfterAllEventPacketsAreCompleted) {
constexpr uint32_t packetsInUse = 2;
event->setPacketsInUse(packetsInUse);
const size_t eventPacketSize = event->getSinglePacketSize();
const size_t eventCompletionOffset = event->getContextStartOffset();
VariableBackup<volatile uint32_t *> backupPauseAddress(&CpuIntrinsicsTests::pauseAddress);
VariableBackup<uint32_t> backupPauseValue(&CpuIntrinsicsTests::pauseValue, Event::STATE_CLEARED);
VariableBackup<uint32_t> backupPauseOffset(&CpuIntrinsicsTests::pauseOffset);
VariableBackup<std::function<void()>> backupSetupPauseAddress(&CpuIntrinsicsTests::setupPauseAddress);
CpuIntrinsicsTests::pauseCounter = 0u;
CpuIntrinsicsTests::pauseAddress = static_cast<uint32_t *>(ptrOffset(event->getHostAddress(), eventCompletionOffset));
uint32_t *hostAddr = static_cast<uint32_t *>(ptrOffset(event->getHostAddress(), eventCompletionOffset));
for (uint32_t i = 0; i < packetsInUse; i++) {
*hostAddr = Event::STATE_CLEARED;
hostAddr = ptrOffset(hostAddr, eventPacketSize);
}
CpuIntrinsicsTests::setupPauseAddress = [&]() {
if (CpuIntrinsicsTests::pauseCounter > 10) {
volatile uint32_t *nextPacket = CpuIntrinsicsTests::pauseAddress;
for (uint32_t i = 0; i < packetsInUse; i++) {
*nextPacket = Event::STATE_SIGNALED;
nextPacket = ptrOffset(nextPacket, eventPacketSize);
}
}
};
constexpr uint64_t infiniteTimeout = std::numeric_limits<std::uint64_t>::max();
ze_result_t result = event->hostSynchronize(infiniteTimeout);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(EventSynchronizeTest, givenInfiniteTimeoutWhenWaitingForTimestampEventCompletionThenReturnOnlyAfterAllEventPacketsAreCompleted) {
constexpr uint32_t packetsInUse = 2;
event->setPacketsInUse(packetsInUse);
event->setEventTimestampFlag(true);
const size_t eventPacketSize = event->getSinglePacketSize();
const size_t eventCompletionOffset = event->getContextEndOffset();
VariableBackup<volatile uint32_t *> backupPauseAddress(&CpuIntrinsicsTests::pauseAddress);
VariableBackup<uint32_t> backupPauseValue(&CpuIntrinsicsTests::pauseValue, Event::STATE_CLEARED);
VariableBackup<uint32_t> backupPauseOffset(&CpuIntrinsicsTests::pauseOffset);
VariableBackup<std::function<void()>> backupSetupPauseAddress(&CpuIntrinsicsTests::setupPauseAddress);
CpuIntrinsicsTests::pauseCounter = 0u;
CpuIntrinsicsTests::pauseAddress = static_cast<uint32_t *>(ptrOffset(event->getHostAddress(), eventCompletionOffset));
uint32_t *hostAddr = static_cast<uint32_t *>(ptrOffset(event->getHostAddress(), eventCompletionOffset));
for (uint32_t i = 0; i < packetsInUse; i++) {
*hostAddr = Event::STATE_CLEARED;
hostAddr = ptrOffset(hostAddr, eventPacketSize);
}
CpuIntrinsicsTests::setupPauseAddress = [&]() {
if (CpuIntrinsicsTests::pauseCounter > 10) {
volatile uint32_t *nextPacket = CpuIntrinsicsTests::pauseAddress;
for (uint32_t i = 0; i < packetsInUse; i++) {
*nextPacket = Event::STATE_SIGNALED;
nextPacket = ptrOffset(nextPacket, eventPacketSize);
}
}
};
constexpr uint64_t infiniteTimeout = std::numeric_limits<std::uint64_t>::max();
ze_result_t result = event->hostSynchronize(infiniteTimeout);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
using EventPoolIPCEventResetTests = Test<DeviceFixture>;
TEST_F(EventPoolIPCEventResetTests, whenOpeningIpcHandleForEventPoolCreateWithIpcFlagThenEventsInNewPoolAreNotReset) {

View File

@ -71,8 +71,8 @@ TEST_F(FenceTest, GivenGpuHangWhenHostSynchronizeIsCalledThenDeviceLostIsReturne
fence->taskCount = 1;
fence->gpuHangCheckPeriod = 0ms;
const auto timeout = std::numeric_limits<std::uint32_t>::max();
const auto result = fence->hostSynchronize(timeout);
constexpr uint64_t timeout = std::numeric_limits<std::uint64_t>::max();
auto result = fence->hostSynchronize(timeout);
EXPECT_EQ(ZE_RESULT_ERROR_DEVICE_LOST, result);
}
@ -92,8 +92,8 @@ TEST_F(FenceTest, GivenNoGpuHangAndOneNanosecondTimeoutWhenHostSynchronizeIsCall
fence->taskCount = 1;
fence->gpuHangCheckPeriod = 0ms;
const auto timeoutNanoseconds = 1;
const auto result = fence->hostSynchronize(timeoutNanoseconds);
constexpr uint64_t timeoutNanoseconds = 1;
auto result = fence->hostSynchronize(timeoutNanoseconds);
EXPECT_EQ(ZE_RESULT_NOT_READY, result);
}
@ -112,8 +112,8 @@ TEST_F(FenceTest, GivenLongPeriodOfGpuCheckAndOneNanosecondTimeoutWhenHostSynchr
fence->taskCount = 1;
fence->gpuHangCheckPeriod = 50000000ms;
const auto timeoutNanoseconds = 1;
const auto result = fence->hostSynchronize(timeoutNanoseconds);
constexpr uint64_t timeoutNanoseconds = 1;
auto result = fence->hostSynchronize(timeoutNanoseconds);
EXPECT_EQ(ZE_RESULT_NOT_READY, result);
}
@ -131,8 +131,8 @@ TEST_F(FenceTest, GivenSuccessfulQueryResultAndNoTimeoutWhenHostSynchronizeIsCal
fence->taskCount = 1;
const auto timeout = std::numeric_limits<std::uint32_t>::max();
const auto result = fence->hostSynchronize(timeout);
constexpr uint64_t timeout = std::numeric_limits<std::uint32_t>::max();
auto result = fence->hostSynchronize(timeout);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}

View File

@ -71,6 +71,7 @@ class TimestampPackets : public TagTypeBase {
uint64_t getGlobalEndValue(uint32_t packetIndex) const { return static_cast<uint64_t>(packets[packetIndex].globalEnd); }
void const *getContextEndAddress(uint32_t packetIndex) const { return static_cast<void const *>(&packets[packetIndex].contextEnd); }
void const *getContextStartAddress(uint32_t packetIndex) const { return static_cast<void const *>(&packets[packetIndex].contextStart); }
protected:
Packet packets[TimestampPacketSizeControl::preferredPacketCount];