From acf97999f33d76974c5ce84946e79e898b0374ff Mon Sep 17 00:00:00 2001 From: "Dunajski, Bartosz" Date: Tue, 10 Apr 2018 10:26:59 +0200 Subject: [PATCH] Force Kmd Notify timeout for Windows machines running on battery - This is to improve battery usage while waiting in busy loop on CPU - New Kmd Notify helper to maintain dynamic parameters - Ask OS about battery status on longer waits - Pick different timeout when using battery and optimization is disabled Change-Id: I5f9c8c5a9c635652aac27c707f2b55933947a7fb --- .../builtin_kernels_simulation/CMakeLists.txt | 2 +- .../command_stream_receiver_hw.h | 5 +- .../command_stream_receiver_hw.inl | 31 ++- runtime/helpers/CMakeLists.txt | 6 + runtime/helpers/kmd_notify_properties.cpp | 46 ++-- runtime/helpers/kmd_notify_properties.h | 29 ++- .../linux/kmd_notify_properties_linux.cpp | 25 +++ .../windows/kmd_notify_properties_windows.cpp | 32 +++ runtime/os_interface/linux/hw_info_config.cpp | 12 +- .../os_interface/windows/hw_info_config.cpp | 12 +- runtime/os_interface/windows/sys_calls.cpp | 4 + runtime/os_interface/windows/sys_calls.h | 1 + unit_tests/helpers/CMakeLists.txt | 9 + unit_tests/helpers/kmd_notify_tests.cpp | 202 +++++++++++++----- .../windows/kmd_notify_windows_tests.cpp | 77 +++++++ .../libult/ult_command_stream_receiver.h | 1 - unit_tests/os_interface/windows/sys_calls.cpp | 8 + 17 files changed, 397 insertions(+), 105 deletions(-) create mode 100644 runtime/helpers/linux/kmd_notify_properties_linux.cpp create mode 100644 runtime/helpers/windows/kmd_notify_properties_windows.cpp create mode 100644 unit_tests/helpers/windows/kmd_notify_windows_tests.cpp diff --git a/runtime/builtin_kernels_simulation/CMakeLists.txt b/runtime/builtin_kernels_simulation/CMakeLists.txt index 5ac04b9ca2..3d7f24af49 100644 --- a/runtime/builtin_kernels_simulation/CMakeLists.txt +++ b/runtime/builtin_kernels_simulation/CMakeLists.txt @@ -64,4 +64,4 @@ target_include_directories(${BIKSIM_LIB_NAME} BEFORE PRIVATE ${THIRD_PARTY_DIR} ) set_target_properties(${BIKSIM_LIB_NAME} PROPERTIES FOLDER "built_ins") -target_compile_definitions(${BIKSIM_LIB_NAME} PUBLIC ${SUPPORTED_GEN_FLAGS_DEFINITONS} ${DEFAULT_GEN_PLATFORMS_DEFITIONS}) +target_compile_definitions(${BIKSIM_LIB_NAME} PUBLIC ${SUPPORTED_GEN_FLAGS_DEFINITONS} ${DEFAULT_GEN_PLATFORMS_DEFITIONS} MOCKABLE_VIRTUAL=) diff --git a/runtime/command_stream/command_stream_receiver_hw.h b/runtime/command_stream/command_stream_receiver_hw.h index 6c0ed6b316..1ce9c567b6 100644 --- a/runtime/command_stream/command_stream_receiver_hw.h +++ b/runtime/command_stream/command_stream_receiver_hw.h @@ -76,6 +76,8 @@ class CommandStreamReceiverHw : public CommandStreamReceiver { uint64_t generalStateBase, uint64_t internalHeapBaseAddress); + void resetKmdNotifyHelper(KmdNotifyHelper *newHelper); + protected: void programPreemption(LinearStream &csr, DispatchFlags &dispatchFlags); void programL3(LinearStream &csr, DispatchFlags &dispatchFlags, uint32_t &newL3Config); @@ -90,7 +92,6 @@ class CommandStreamReceiverHw : public CommandStreamReceiver { PIPE_CONTROL *addPipeControlCmd(LinearStream &commandStream); uint64_t getScratchPatchAddress(); - MOCKABLE_VIRTUAL void updateLastWaitForCompletionTimestamp(); static void emitNoop(LinearStream &commandStream, size_t bytesToUpdate); @@ -101,7 +102,7 @@ class CommandStreamReceiverHw : public CommandStreamReceiver { const HardwareInfo &hwInfo; CsrSizeRequestFlags csrSizeRequestFlags = {}; - std::chrono::high_resolution_clock::time_point lastWaitForCompletionTimestamp; + std::unique_ptr kmdNotifyHelper; }; template diff --git a/runtime/command_stream/command_stream_receiver_hw.inl b/runtime/command_stream/command_stream_receiver_hw.inl index 5d3221d6aa..1e3137129a 100644 --- a/runtime/command_stream/command_stream_receiver_hw.inl +++ b/runtime/command_stream/command_stream_receiver_hw.inl @@ -40,9 +40,7 @@ namespace OCLRT { template CommandStreamReceiverHw::CommandStreamReceiverHw(const HardwareInfo &hwInfoIn) : hwInfo(hwInfoIn) { requiredThreadArbitrationPolicy = PreambleHelper::getDefaultThreadArbitrationPolicy(); - if (hwInfo.capabilityTable.kmdNotifyProperties.enableQuickKmdSleepForSporadicWaits) { - lastWaitForCompletionTimestamp = std::chrono::high_resolution_clock::now(); - } + resetKmdNotifyHelper(new KmdNotifyHelper(&(hwInfoIn.capabilityTable.kmdNotifyProperties))); } template @@ -568,13 +566,10 @@ inline void CommandStreamReceiverHw::emitNoop(LinearStream &commandSt template inline void CommandStreamReceiverHw::waitForTaskCountWithKmdNotifyFallback(uint32_t taskCountToWait, FlushStamp flushStampToWait, bool useQuickKmdSleep) { - const auto &kmdNotifyProperties = this->hwInfo.capabilityTable.kmdNotifyProperties; + int64_t waitTimeout = 0; + bool enableTimeout = kmdNotifyHelper->obtainTimeoutParams(waitTimeout, useQuickKmdSleep, *getTagAddress(), taskCountToWait, flushStampToWait); - int64_t waitTimeout = kmdNotifyProperties.pickTimeoutValue(lastWaitForCompletionTimestamp, useQuickKmdSleep, *getTagAddress(), taskCountToWait); - - auto status = waitForCompletionWithTimeout(kmdNotifyProperties.timeoutEnabled(flushStampToWait), - waitTimeout, - taskCountToWait); + auto status = waitForCompletionWithTimeout(enableTimeout, waitTimeout, taskCountToWait); if (!status) { waitForFlushStamp(flushStampToWait); //now call blocking wait, this is to ensure that task count is reached @@ -582,8 +577,8 @@ inline void CommandStreamReceiverHw::waitForTaskCountWithKmdNotifyFal } UNRECOVERABLE_IF(*getTagAddress() < taskCountToWait); - if (kmdNotifyProperties.enableQuickKmdSleepForSporadicWaits) { - updateLastWaitForCompletionTimestamp(); + if (kmdNotifyHelper->quickKmdSleepForSporadicWaitsEnabled()) { + kmdNotifyHelper->updateLastWaitForCompletionTimestamp(); } } @@ -636,11 +631,6 @@ size_t CommandStreamReceiverHw::getCmdSizeForMediaSampler(bool mediaS return 0; } -template -void CommandStreamReceiverHw::updateLastWaitForCompletionTimestamp() { - lastWaitForCompletionTimestamp = std::chrono::high_resolution_clock::now(); -} - template void CommandStreamReceiverHw::collectStateBaseAddresPatchInfo( uint64_t baseAddress, @@ -666,4 +656,13 @@ void CommandStreamReceiverHw::collectStateBaseAddresPatchInfo( setPatchInfoData(instructionPatchInfo); } +template +void CommandStreamReceiverHw::resetKmdNotifyHelper(KmdNotifyHelper *newHelper) { + kmdNotifyHelper.reset(newHelper); + kmdNotifyHelper->updateAcLineStatus(); + if (kmdNotifyHelper->quickKmdSleepForSporadicWaitsEnabled()) { + kmdNotifyHelper->updateLastWaitForCompletionTimestamp(); + } +} + } // namespace OCLRT diff --git a/runtime/helpers/CMakeLists.txt b/runtime/helpers/CMakeLists.txt index 19c085e9bc..31666b690a 100644 --- a/runtime/helpers/CMakeLists.txt +++ b/runtime/helpers/CMakeLists.txt @@ -88,11 +88,17 @@ set(RUNTIME_SRCS_HELPERS_BASE set(RUNTIME_SRCS_HELPERS_WINDOWS ${CMAKE_CURRENT_SOURCE_DIR}/translationtable_callbacks.h ${CMAKE_CURRENT_SOURCE_DIR}/translationtable_callbacks.inl + ${CMAKE_CURRENT_SOURCE_DIR}/windows/kmd_notify_properties_windows.cpp ${CMAKE_CURRENT_SOURCE_DIR}/wddm_helper.h ) +set(RUNTIME_SRCS_HELPERS_LINUX + ${CMAKE_CURRENT_SOURCE_DIR}/linux/kmd_notify_properties_linux.cpp +) target_sources(${NEO_STATIC_LIB_NAME} PRIVATE ${RUNTIME_SRCS_HELPERS_BASE}) if(WIN32) target_sources(${NEO_STATIC_LIB_NAME} PRIVATE ${RUNTIME_SRCS_HELPERS_WINDOWS}) +else() + target_sources(${NEO_STATIC_LIB_NAME} PRIVATE ${RUNTIME_SRCS_HELPERS_LINUX}) endif() set_property(GLOBAL PROPERTY RUNTIME_SRCS_HELPERS_BASE ${RUNTIME_SRCS_HELPERS_BASE}) diff --git a/runtime/helpers/kmd_notify_properties.cpp b/runtime/helpers/kmd_notify_properties.cpp index fe9b0be274..5dbbee82eb 100644 --- a/runtime/helpers/kmd_notify_properties.cpp +++ b/runtime/helpers/kmd_notify_properties.cpp @@ -25,41 +25,51 @@ using namespace OCLRT; -bool KmdNotifyProperties::timeoutEnabled(FlushStamp flushStampToWait) const { - return enableKmdNotify && flushStampToWait != 0; -} - -int64_t KmdNotifyProperties::pickTimeoutValue(std::chrono::high_resolution_clock::time_point &lastWaitTimestamp, - bool quickKmdSleepRequest, uint32_t currentHwTag, uint32_t taskCountToWait) const { - quickKmdSleepRequest |= applyQuickKmdSleepForSporadicWait(lastWaitTimestamp); - - if (quickKmdSleepRequest && enableQuickKmdSleep) { - return delayQuickKmdSleepMicroseconds; +bool KmdNotifyHelper::obtainTimeoutParams(int64_t &timeoutValueOutput, + bool quickKmdSleepRequest, + uint32_t currentHwTag, + uint32_t taskCountToWait, + FlushStamp flushStampToWait) { + int64_t multiplier = (currentHwTag < taskCountToWait) ? static_cast(taskCountToWait - currentHwTag) : 1; + if (!properties->enableKmdNotify && multiplier > KmdNotifyConstants::minimumTaskCountDiffToCheckAcLine) { + updateAcLineStatus(); } - int64_t multiplier = (currentHwTag < taskCountToWait) ? static_cast(taskCountToWait - currentHwTag) : 1; + quickKmdSleepRequest |= applyQuickKmdSleepForSporadicWait(); - return delayKmdNotifyMicroseconds * multiplier; + if (!properties->enableKmdNotify && !acLineConnected) { + timeoutValueOutput = KmdNotifyConstants::timeoutInMicrosecondsForDisconnectedAcLine; + } else if (quickKmdSleepRequest && properties->enableQuickKmdSleep) { + timeoutValueOutput = properties->delayQuickKmdSleepMicroseconds; + } else { + timeoutValueOutput = properties->delayKmdNotifyMicroseconds * multiplier; + } + + return flushStampToWait != 0 && (properties->enableKmdNotify || !acLineConnected); } -bool KmdNotifyProperties::applyQuickKmdSleepForSporadicWait(std::chrono::high_resolution_clock::time_point &lastWaitTimestamp) const { - if (enableQuickKmdSleepForSporadicWaits) { +bool KmdNotifyHelper::applyQuickKmdSleepForSporadicWait() const { + if (properties->enableQuickKmdSleepForSporadicWaits) { auto now = std::chrono::high_resolution_clock::now(); - auto timeDiff = std::chrono::duration_cast(now - lastWaitTimestamp).count(); - if (timeDiff > delayQuickKmdSleepForSporadicWaitsMicroseconds) { + auto timeDiff = std::chrono::duration_cast(now - lastWaitForCompletionTimestamp).count(); + if (timeDiff > properties->delayQuickKmdSleepForSporadicWaitsMicroseconds) { return true; } } return false; } -void KmdNotifyProperties::overrideFromDebugVariable(int32_t debugVariableValue, int64_t &destination) { +void KmdNotifyHelper::updateLastWaitForCompletionTimestamp() { + lastWaitForCompletionTimestamp = std::chrono::high_resolution_clock::now(); +} + +void KmdNotifyHelper::overrideFromDebugVariable(int32_t debugVariableValue, int64_t &destination) { if (debugVariableValue >= 0) { destination = static_cast(debugVariableValue); } } -void KmdNotifyProperties::overrideFromDebugVariable(int32_t debugVariableValue, bool &destination) { +void KmdNotifyHelper::overrideFromDebugVariable(int32_t debugVariableValue, bool &destination) { if (debugVariableValue >= 0) { destination = !!(debugVariableValue); } diff --git a/runtime/helpers/kmd_notify_properties.h b/runtime/helpers/kmd_notify_properties.h index 2b922e02b1..98800433d9 100644 --- a/runtime/helpers/kmd_notify_properties.h +++ b/runtime/helpers/kmd_notify_properties.h @@ -37,15 +37,36 @@ struct KmdNotifyProperties { // If waits are called sporadically use QuickKmdSleep mode, otherwise use standard delay bool enableQuickKmdSleepForSporadicWaits; int64_t delayQuickKmdSleepForSporadicWaitsMicroseconds; +}; - bool timeoutEnabled(FlushStamp flushStampToWait) const; +namespace KmdNotifyConstants { +constexpr int64_t timeoutInMicrosecondsForDisconnectedAcLine = 10000; +constexpr uint32_t minimumTaskCountDiffToCheckAcLine = 10; +} // namespace KmdNotifyConstants - int64_t pickTimeoutValue(std::chrono::high_resolution_clock::time_point &lastWaitTimestamp, - bool quickKmdSleepRequest, uint32_t currentHwTag, uint32_t taskCountToWait) const; +class KmdNotifyHelper { + public: + KmdNotifyHelper() = delete; + KmdNotifyHelper(const KmdNotifyProperties *properties) : properties(properties){}; - bool applyQuickKmdSleepForSporadicWait(std::chrono::high_resolution_clock::time_point &lastWaitTimestamp) const; + bool obtainTimeoutParams(int64_t &timeoutValueOutput, + bool quickKmdSleepRequest, + uint32_t currentHwTag, + uint32_t taskCountToWait, + FlushStamp flushStampToWait); + + bool quickKmdSleepForSporadicWaitsEnabled() const { return properties->enableQuickKmdSleepForSporadicWaits; } + MOCKABLE_VIRTUAL void updateLastWaitForCompletionTimestamp(); + MOCKABLE_VIRTUAL void updateAcLineStatus(); static void overrideFromDebugVariable(int32_t debugVariableValue, int64_t &destination); static void overrideFromDebugVariable(int32_t debugVariableValue, bool &destination); + + protected: + bool applyQuickKmdSleepForSporadicWait() const; + + const KmdNotifyProperties *properties = nullptr; + std::chrono::high_resolution_clock::time_point lastWaitForCompletionTimestamp; + bool acLineConnected = true; }; } // namespace OCLRT diff --git a/runtime/helpers/linux/kmd_notify_properties_linux.cpp b/runtime/helpers/linux/kmd_notify_properties_linux.cpp new file mode 100644 index 0000000000..ccdb21f235 --- /dev/null +++ b/runtime/helpers/linux/kmd_notify_properties_linux.cpp @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2018, Intel Corporation +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "runtime/helpers/kmd_notify_properties.h" + +void OCLRT::KmdNotifyHelper::updateAcLineStatus() {} diff --git a/runtime/helpers/windows/kmd_notify_properties_windows.cpp b/runtime/helpers/windows/kmd_notify_properties_windows.cpp new file mode 100644 index 0000000000..eae99fb117 --- /dev/null +++ b/runtime/helpers/windows/kmd_notify_properties_windows.cpp @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2018, Intel Corporation +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +* OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "runtime/helpers/kmd_notify_properties.h" +#include "runtime/os_interface/windows/sys_calls.h" + +void OCLRT::KmdNotifyHelper::updateAcLineStatus() { + SYSTEM_POWER_STATUS systemPowerStatus = {}; + auto powerStatusRetValue = SysCalls::getSystemPowerStatus(&systemPowerStatus); + if (powerStatusRetValue == 1) { + acLineConnected = (systemPowerStatus.ACLineStatus == 1); + } +} diff --git a/runtime/os_interface/linux/hw_info_config.cpp b/runtime/os_interface/linux/hw_info_config.cpp index 9cbbab2b00..7961f506b4 100644 --- a/runtime/os_interface/linux/hw_info_config.cpp +++ b/runtime/os_interface/linux/hw_info_config.cpp @@ -183,12 +183,12 @@ int HwInfoConfig::configureHwInfo(const HardwareInfo *inHwInfo, HardwareInfo *ou outHwInfo->capabilityTable.requiredPreemptionSurfaceSize = outHwInfo->pSysInfo->CsrSizeInMb * MemoryConstants::megaByte; auto &kmdNotifyProperties = outHwInfo->capabilityTable.kmdNotifyProperties; - KmdNotifyProperties::overrideFromDebugVariable(DebugManager.flags.OverrideEnableKmdNotify.get(), kmdNotifyProperties.enableKmdNotify); - KmdNotifyProperties::overrideFromDebugVariable(DebugManager.flags.OverrideKmdNotifyDelayMicroseconds.get(), kmdNotifyProperties.delayKmdNotifyMicroseconds); - KmdNotifyProperties::overrideFromDebugVariable(DebugManager.flags.OverrideEnableQuickKmdSleep.get(), kmdNotifyProperties.enableQuickKmdSleep); - KmdNotifyProperties::overrideFromDebugVariable(DebugManager.flags.OverrideQuickKmdSleepDelayMicroseconds.get(), kmdNotifyProperties.delayQuickKmdSleepMicroseconds); - KmdNotifyProperties::overrideFromDebugVariable(DebugManager.flags.OverrideEnableQuickKmdSleepForSporadicWaits.get(), kmdNotifyProperties.enableQuickKmdSleepForSporadicWaits); - KmdNotifyProperties::overrideFromDebugVariable(DebugManager.flags.OverrideDelayQuickKmdSleepForSporadicWaitsMicroseconds.get(), kmdNotifyProperties.delayQuickKmdSleepForSporadicWaitsMicroseconds); + KmdNotifyHelper::overrideFromDebugVariable(DebugManager.flags.OverrideEnableKmdNotify.get(), kmdNotifyProperties.enableKmdNotify); + KmdNotifyHelper::overrideFromDebugVariable(DebugManager.flags.OverrideKmdNotifyDelayMicroseconds.get(), kmdNotifyProperties.delayKmdNotifyMicroseconds); + KmdNotifyHelper::overrideFromDebugVariable(DebugManager.flags.OverrideEnableQuickKmdSleep.get(), kmdNotifyProperties.enableQuickKmdSleep); + KmdNotifyHelper::overrideFromDebugVariable(DebugManager.flags.OverrideQuickKmdSleepDelayMicroseconds.get(), kmdNotifyProperties.delayQuickKmdSleepMicroseconds); + KmdNotifyHelper::overrideFromDebugVariable(DebugManager.flags.OverrideEnableQuickKmdSleepForSporadicWaits.get(), kmdNotifyProperties.enableQuickKmdSleepForSporadicWaits); + KmdNotifyHelper::overrideFromDebugVariable(DebugManager.flags.OverrideDelayQuickKmdSleepForSporadicWaitsMicroseconds.get(), kmdNotifyProperties.delayQuickKmdSleepForSporadicWaitsMicroseconds); pPlatform.release(); pSkuTable.release(); diff --git a/runtime/os_interface/windows/hw_info_config.cpp b/runtime/os_interface/windows/hw_info_config.cpp index a18309f5f7..a50930cf52 100644 --- a/runtime/os_interface/windows/hw_info_config.cpp +++ b/runtime/os_interface/windows/hw_info_config.cpp @@ -56,12 +56,12 @@ int HwInfoConfig::configureHwInfo(const HardwareInfo *inHwInfo, HardwareInfo *ou outHwInfo->capabilityTable.instrumentationEnabled &= haveInstrumentation; auto &kmdNotifyProperties = outHwInfo->capabilityTable.kmdNotifyProperties; - KmdNotifyProperties::overrideFromDebugVariable(DebugManager.flags.OverrideEnableKmdNotify.get(), kmdNotifyProperties.enableKmdNotify); - KmdNotifyProperties::overrideFromDebugVariable(DebugManager.flags.OverrideKmdNotifyDelayMicroseconds.get(), kmdNotifyProperties.delayKmdNotifyMicroseconds); - KmdNotifyProperties::overrideFromDebugVariable(DebugManager.flags.OverrideEnableQuickKmdSleep.get(), kmdNotifyProperties.enableQuickKmdSleep); - KmdNotifyProperties::overrideFromDebugVariable(DebugManager.flags.OverrideQuickKmdSleepDelayMicroseconds.get(), kmdNotifyProperties.delayQuickKmdSleepMicroseconds); - KmdNotifyProperties::overrideFromDebugVariable(DebugManager.flags.OverrideEnableQuickKmdSleepForSporadicWaits.get(), kmdNotifyProperties.enableQuickKmdSleepForSporadicWaits); - KmdNotifyProperties::overrideFromDebugVariable(DebugManager.flags.OverrideDelayQuickKmdSleepForSporadicWaitsMicroseconds.get(), kmdNotifyProperties.delayQuickKmdSleepForSporadicWaitsMicroseconds); + KmdNotifyHelper::overrideFromDebugVariable(DebugManager.flags.OverrideEnableKmdNotify.get(), kmdNotifyProperties.enableKmdNotify); + KmdNotifyHelper::overrideFromDebugVariable(DebugManager.flags.OverrideKmdNotifyDelayMicroseconds.get(), kmdNotifyProperties.delayKmdNotifyMicroseconds); + KmdNotifyHelper::overrideFromDebugVariable(DebugManager.flags.OverrideEnableQuickKmdSleep.get(), kmdNotifyProperties.enableQuickKmdSleep); + KmdNotifyHelper::overrideFromDebugVariable(DebugManager.flags.OverrideQuickKmdSleepDelayMicroseconds.get(), kmdNotifyProperties.delayQuickKmdSleepMicroseconds); + KmdNotifyHelper::overrideFromDebugVariable(DebugManager.flags.OverrideEnableQuickKmdSleepForSporadicWaits.get(), kmdNotifyProperties.enableQuickKmdSleepForSporadicWaits); + KmdNotifyHelper::overrideFromDebugVariable(DebugManager.flags.OverrideDelayQuickKmdSleepForSporadicWaitsMicroseconds.get(), kmdNotifyProperties.delayQuickKmdSleepForSporadicWaitsMicroseconds); // Product specific config int ret = configureHardwareCustom(outHwInfo, osIface); diff --git a/runtime/os_interface/windows/sys_calls.cpp b/runtime/os_interface/windows/sys_calls.cpp index cda99189b1..b94f2029d3 100644 --- a/runtime/os_interface/windows/sys_calls.cpp +++ b/runtime/os_interface/windows/sys_calls.cpp @@ -34,6 +34,10 @@ BOOL closeHandle(HANDLE hObject) { return CloseHandle(hObject); } +BOOL getSystemPowerStatus(LPSYSTEM_POWER_STATUS systemPowerStatusPtr) { + return GetSystemPowerStatus(systemPowerStatusPtr); +} + } // namespace SysCalls } // namespace OCLRT diff --git a/runtime/os_interface/windows/sys_calls.h b/runtime/os_interface/windows/sys_calls.h index 3d836dce38..e0a34bfc3d 100644 --- a/runtime/os_interface/windows/sys_calls.h +++ b/runtime/os_interface/windows/sys_calls.h @@ -29,6 +29,7 @@ namespace SysCalls { HANDLE createEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCSTR lpName); BOOL closeHandle(HANDLE hObject); +BOOL getSystemPowerStatus(LPSYSTEM_POWER_STATUS systemPowerStatusPtr); } // namespace SysCalls diff --git a/unit_tests/helpers/CMakeLists.txt b/unit_tests/helpers/CMakeLists.txt index 0d1901d4eb..56163bf917 100644 --- a/unit_tests/helpers/CMakeLists.txt +++ b/unit_tests/helpers/CMakeLists.txt @@ -54,4 +54,13 @@ set(IGDRCL_SRCS_tests_helpers ${CMAKE_CURRENT_SOURCE_DIR}/uint16_sse4_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/validator_tests.cpp ) + +set(IGDRCL_SRCS_tests_helpers_windows + ${CMAKE_CURRENT_SOURCE_DIR}/windows/kmd_notify_windows_tests.cpp +) + +if(WIN32) + target_sources(igdrcl_tests PRIVATE ${IGDRCL_SRCS_tests_helpers_windows}) +endif() + target_sources(igdrcl_tests PRIVATE ${IGDRCL_SRCS_tests_helpers}) diff --git a/unit_tests/helpers/kmd_notify_tests.cpp b/unit_tests/helpers/kmd_notify_tests.cpp index 17206285d6..39fac8e573 100644 --- a/unit_tests/helpers/kmd_notify_tests.cpp +++ b/unit_tests/helpers/kmd_notify_tests.cpp @@ -54,14 +54,48 @@ struct KmdNotifyTests : public ::testing::Test { properties.delayQuickKmdSleepForSporadicWaitsMicroseconds = quickKmdSleepDelayForSporadicWaits; } - template - class MyCsr : public UltCommandStreamReceiver { + class MockKmdNotifyHelper : public KmdNotifyHelper { public: - MyCsr(const HardwareInfo &hwInfo) : UltCommandStreamReceiver(hwInfo) {} + using KmdNotifyHelper::acLineConnected; + using KmdNotifyHelper::lastWaitForCompletionTimestamp; + + MockKmdNotifyHelper() = delete; + MockKmdNotifyHelper(const KmdNotifyProperties *newProperties) : KmdNotifyHelper(newProperties){}; + + void updateLastWaitForCompletionTimestamp() override { + KmdNotifyHelper::updateLastWaitForCompletionTimestamp(); + updateLastWaitForCompletionTimestampCalled++; + } + + void updateAcLineStatus() override { + KmdNotifyHelper::updateAcLineStatus(); + updateAcLineStatusCalled++; + } + + uint32_t updateLastWaitForCompletionTimestampCalled = 0u; + uint32_t updateAcLineStatusCalled = 0u; + }; + + template + class MockKmdNotifyCsr : public UltCommandStreamReceiver { + public: + MockKmdNotifyCsr(const HardwareInfo &hwInfo) : UltCommandStreamReceiver(hwInfo) {} MOCK_METHOD1(waitForFlushStamp, bool(FlushStamp &flushStampToWait)); MOCK_METHOD3(waitForCompletionWithTimeout, bool(bool enableTimeout, int64_t timeoutMs, uint32_t taskCountToWait)); }; + template + MockKmdNotifyCsr *createMockCsr() { + auto csr = new ::testing::NiceMock>(device->getHardwareInfo()); + device->resetCommandStreamReceiver(csr); + + mockKmdNotifyHelper = new MockKmdNotifyHelper(&device->getHardwareInfo().capabilityTable.kmdNotifyProperties); + csr->resetKmdNotifyHelper(mockKmdNotifyHelper); + + return csr; + } + + MockKmdNotifyHelper *mockKmdNotifyHelper = nullptr; HardwareInfo localHwInfo = **platformDevices; MockContext context; std::unique_ptr device; @@ -71,8 +105,7 @@ struct KmdNotifyTests : public ::testing::Test { }; HWTEST_F(KmdNotifyTests, givenTaskCountWhenWaitUntilCompletionCalledThenAlwaysTryCpuPolling) { - auto csr = new ::testing::NiceMock>(device->getHardwareInfo()); - device->resetCommandStreamReceiver(csr); + auto csr = createMockCsr(); EXPECT_CALL(*csr, waitForCompletionWithTimeout(true, 2, taskCountToWait)).Times(1).WillOnce(::testing::Return(true)); @@ -81,8 +114,7 @@ HWTEST_F(KmdNotifyTests, givenTaskCountWhenWaitUntilCompletionCalledThenAlwaysTr HWTEST_F(KmdNotifyTests, givenTaskCountAndKmdNotifyDisabledWhenWaitUntilCompletionCalledThenTryCpuPollingWithoutTimeout) { overrideKmdNotifyParams(false, 0, false, 0, false, 0); - auto csr = new ::testing::NiceMock>(device->getHardwareInfo()); - device->resetCommandStreamReceiver(csr); + auto csr = createMockCsr(); EXPECT_CALL(*csr, waitForCompletionWithTimeout(false, 0, taskCountToWait)).Times(1).WillOnce(::testing::Return(true)); EXPECT_CALL(*csr, waitForFlushStamp(::testing::_)).Times(0); @@ -91,8 +123,7 @@ HWTEST_F(KmdNotifyTests, givenTaskCountAndKmdNotifyDisabledWhenWaitUntilCompleti } HWTEST_F(KmdNotifyTests, givenNotReadyTaskCountWhenWaitUntilCompletionCalledThenTryCpuPollingAndKmdWait) { - auto csr = new ::testing::NiceMock>(device->getHardwareInfo()); - device->resetCommandStreamReceiver(csr); + auto csr = createMockCsr(); *device->getTagAddress() = taskCountToWait - 1; ::testing::InSequence is; @@ -105,8 +136,7 @@ HWTEST_F(KmdNotifyTests, givenNotReadyTaskCountWhenWaitUntilCompletionCalledThen } HWTEST_F(KmdNotifyTests, givenReadyTaskCountWhenWaitUntilCompletionCalledThenTryCpuPollingAndDontCallKmdWait) { - auto csr = new ::testing::NiceMock>(device->getHardwareInfo()); - device->resetCommandStreamReceiver(csr); + auto csr = createMockCsr(); ::testing::InSequence is; EXPECT_CALL(*csr, waitForCompletionWithTimeout(true, 2, taskCountToWait)).Times(1).WillOnce(::testing::Return(true)); @@ -116,8 +146,7 @@ HWTEST_F(KmdNotifyTests, givenReadyTaskCountWhenWaitUntilCompletionCalledThenTry } HWTEST_F(KmdNotifyTests, givenDefaultArgumentWhenWaitUntilCompleteIsCalledThenDisableQuickKmdSleep) { - auto csr = new ::testing::NiceMock>(device->getHardwareInfo()); - device->resetCommandStreamReceiver(csr); + auto csr = createMockCsr(); auto expectedTimeout = device->getHardwareInfo().capabilityTable.kmdNotifyProperties.delayKmdNotifyMicroseconds; EXPECT_CALL(*csr, waitForCompletionWithTimeout(true, expectedTimeout, taskCountToWait)).Times(1).WillOnce(::testing::Return(true)); @@ -126,8 +155,7 @@ HWTEST_F(KmdNotifyTests, givenDefaultArgumentWhenWaitUntilCompleteIsCalledThenDi } HWTEST_F(KmdNotifyTests, givenEnabledQuickSleepWhenWaitUntilCompleteIsCalledThenChangeDelayValue) { - auto csr = new ::testing::NiceMock>(device->getHardwareInfo()); - device->resetCommandStreamReceiver(csr); + auto csr = createMockCsr(); auto expectedTimeout = device->getHardwareInfo().capabilityTable.kmdNotifyProperties.delayQuickKmdSleepMicroseconds; EXPECT_CALL(*csr, waitForCompletionWithTimeout(true, expectedTimeout, taskCountToWait)).Times(1).WillOnce(::testing::Return(true)); @@ -137,8 +165,7 @@ HWTEST_F(KmdNotifyTests, givenEnabledQuickSleepWhenWaitUntilCompleteIsCalledThen HWTEST_F(KmdNotifyTests, givenDisabledQuickSleepWhenWaitUntilCompleteWithQuickSleepRequestIsCalledThenUseBaseDelayValue) { overrideKmdNotifyParams(true, 1, false, 0, false, 0); - auto csr = new ::testing::NiceMock>(device->getHardwareInfo()); - device->resetCommandStreamReceiver(csr); + auto csr = createMockCsr(); auto expectedTimeout = device->getHardwareInfo().capabilityTable.kmdNotifyProperties.delayKmdNotifyMicroseconds; EXPECT_CALL(*csr, waitForCompletionWithTimeout(true, expectedTimeout, taskCountToWait)).Times(1).WillOnce(::testing::Return(true)); @@ -153,8 +180,7 @@ HWTEST_F(KmdNotifyTests, givenNotReadyTaskCountWhenPollForCompletionCalledThenTi } HWTEST_F(KmdNotifyTests, givenZeroFlushStampWhenWaitIsCalledThenDisableTimeout) { - auto csr = new ::testing::NiceMock>(device->getHardwareInfo()); - device->resetCommandStreamReceiver(csr); + auto csr = createMockCsr(); EXPECT_TRUE(device->getHardwareInfo().capabilityTable.kmdNotifyProperties.enableKmdNotify); EXPECT_CALL(*csr, waitForCompletionWithTimeout(false, ::testing::_, taskCountToWait)).Times(1).WillOnce(::testing::Return(true)); @@ -165,21 +191,19 @@ HWTEST_F(KmdNotifyTests, givenZeroFlushStampWhenWaitIsCalledThenDisableTimeout) HWTEST_F(KmdNotifyTests, givenNonQuickSleepRequestWhenItsSporadicWaitThenOverrideQuickSleepRequest) { overrideKmdNotifyParams(true, 3, true, 2, true, 0); - auto csr = new ::testing::NiceMock>(device->getHardwareInfo()); - device->resetCommandStreamReceiver(csr); + auto csr = createMockCsr(); auto expectedDelay = device->getHardwareInfo().capabilityTable.kmdNotifyProperties.delayQuickKmdSleepMicroseconds; EXPECT_CALL(*csr, waitForCompletionWithTimeout(::testing::_, expectedDelay, ::testing::_)).Times(1).WillOnce(::testing::Return(true)); auto now = std::chrono::high_resolution_clock::now(); - csr->lastWaitForCompletionTimestamp = now - std::chrono::hours(24); + mockKmdNotifyHelper->lastWaitForCompletionTimestamp = now - std::chrono::hours(24); csr->waitForTaskCountWithKmdNotifyFallback(taskCountToWait, 1, false); } HWTEST_F(KmdNotifyTests, givenNonQuickSleepRequestWhenItsNotSporadicWaitThenOverrideQuickSleepRequest) { overrideKmdNotifyParams(true, 3, true, 2, true, 9999999); - auto csr = new ::testing::NiceMock>(device->getHardwareInfo()); - device->resetCommandStreamReceiver(csr); + auto csr = createMockCsr(); auto expectedDelay = device->getHardwareInfo().capabilityTable.kmdNotifyProperties.delayKmdNotifyMicroseconds; EXPECT_CALL(*csr, waitForCompletionWithTimeout(::testing::_, expectedDelay, ::testing::_)).Times(1).WillOnce(::testing::Return(true)); @@ -189,8 +213,7 @@ HWTEST_F(KmdNotifyTests, givenNonQuickSleepRequestWhenItsNotSporadicWaitThenOver HWTEST_F(KmdNotifyTests, givenQuickSleepRequestWhenItsSporadicWaitOptimizationIsDisabledThenDontOverrideQuickSleepRequest) { overrideKmdNotifyParams(true, 3, true, 2, false, 0); - auto csr = new ::testing::NiceMock>(device->getHardwareInfo()); - device->resetCommandStreamReceiver(csr); + auto csr = createMockCsr(); auto expectedDelay = device->getHardwareInfo().capabilityTable.kmdNotifyProperties.delayQuickKmdSleepMicroseconds; EXPECT_CALL(*csr, waitForCompletionWithTimeout(::testing::_, expectedDelay, ::testing::_)).Times(1).WillOnce(::testing::Return(true)); @@ -199,8 +222,7 @@ HWTEST_F(KmdNotifyTests, givenQuickSleepRequestWhenItsSporadicWaitOptimizationIs } HWTEST_F(KmdNotifyTests, givenComputeTimeoutMultiplierWhenWaitCalledThenUseNewTimeout) { - auto csr = new ::testing::NiceMock>(device->getHardwareInfo()); - device->resetCommandStreamReceiver(csr); + auto csr = createMockCsr(); *device->getTagAddress() = taskCountToWait; taskCountToWait += 5; @@ -219,9 +241,7 @@ HWTEST_F(KmdNotifyTests, givenComputeTimeoutMultiplierWhenWaitCalledThenUseNewTi } HWTEST_F(KmdNotifyTests, givenTaskCountEqualToHwTagWhenWaitCalledThenDontMultiplyTimeout) { - auto csr = new ::testing::NiceMock>(device->getHardwareInfo()); - device->resetCommandStreamReceiver(csr); - + auto csr = createMockCsr(); *device->getTagAddress() = taskCountToWait; auto expectedTimeout = device->getHardwareInfo().capabilityTable.kmdNotifyProperties.delayKmdNotifyMicroseconds; @@ -232,9 +252,7 @@ HWTEST_F(KmdNotifyTests, givenTaskCountEqualToHwTagWhenWaitCalledThenDontMultipl } HWTEST_F(KmdNotifyTests, givenTaskCountLowerThanHwTagWhenWaitCalledThenDontMultiplyTimeout) { - auto csr = new ::testing::NiceMock>(device->getHardwareInfo()); - device->resetCommandStreamReceiver(csr); - + auto csr = createMockCsr(); *device->getTagAddress() = taskCountToWait + 5; auto expectedTimeout = device->getHardwareInfo().capabilityTable.kmdNotifyProperties.delayKmdNotifyMicroseconds; @@ -244,35 +262,117 @@ HWTEST_F(KmdNotifyTests, givenTaskCountLowerThanHwTagWhenWaitCalledThenDontMulti csr->waitForTaskCountWithKmdNotifyFallback(taskCountToWait, 1, false); } -template -struct MyCsrWithTimestampCheck : public UltCommandStreamReceiver { - MyCsrWithTimestampCheck(const HardwareInfo &hwInfo) : UltCommandStreamReceiver(hwInfo) {} - void updateLastWaitForCompletionTimestamp() override { - updateLastWaitForCompletionTimestampCalled++; - }; - uint32_t updateLastWaitForCompletionTimestampCalled = 0u; -}; - HWTEST_F(KmdNotifyTests, givenDefaultCommandStreamReceiverWhenWaitCalledThenUpdateWaitTimestamp) { overrideKmdNotifyParams(true, 3, true, 2, true, 1); - auto csr = new MyCsrWithTimestampCheck(localHwInfo); - EXPECT_NE(0, csr->lastWaitForCompletionTimestamp.time_since_epoch().count()); - device->resetCommandStreamReceiver(csr); + auto csr = createMockCsr(); + EXPECT_NE(0, mockKmdNotifyHelper->lastWaitForCompletionTimestamp.time_since_epoch().count()); + EXPECT_EQ(1u, mockKmdNotifyHelper->updateLastWaitForCompletionTimestampCalled); csr->waitForTaskCountWithKmdNotifyFallback(0, 0, false); - EXPECT_EQ(1u, csr->updateLastWaitForCompletionTimestampCalled); + EXPECT_EQ(2u, mockKmdNotifyHelper->updateLastWaitForCompletionTimestampCalled); } HWTEST_F(KmdNotifyTests, givenDefaultCommandStreamReceiverWithDisabledSporadicWaitOptimizationWhenWaitCalledThenDontUpdateWaitTimestamp) { overrideKmdNotifyParams(true, 3, true, 2, false, 0); - auto csr = new MyCsrWithTimestampCheck(localHwInfo); - EXPECT_EQ(0, csr->lastWaitForCompletionTimestamp.time_since_epoch().count()); - device->resetCommandStreamReceiver(csr); + auto csr = createMockCsr(); + EXPECT_EQ(0, mockKmdNotifyHelper->lastWaitForCompletionTimestamp.time_since_epoch().count()); csr->waitForTaskCountWithKmdNotifyFallback(0, 0, false); - EXPECT_EQ(0u, csr->updateLastWaitForCompletionTimestampCalled); + EXPECT_EQ(0u, mockKmdNotifyHelper->updateLastWaitForCompletionTimestampCalled); +} + +HWTEST_F(KmdNotifyTests, givenNewHelperWhenItsSetToCsrThenUpdateAcLineStatus) { + auto helper = new MockKmdNotifyHelper(&(localHwInfo.capabilityTable.kmdNotifyProperties)); + EXPECT_EQ(0u, helper->updateAcLineStatusCalled); + + auto csr = createMockCsr(); + csr->resetKmdNotifyHelper(helper); + EXPECT_EQ(1u, helper->updateAcLineStatusCalled); +} + +TEST_F(KmdNotifyTests, givenTaskCountDiffLowerThanMinimumToCheckAcLineWhenObtainingTimeoutPropertiesThenDontCheck) { + localHwInfo.capabilityTable.kmdNotifyProperties.enableKmdNotify = false; + MockKmdNotifyHelper helper(&(localHwInfo.capabilityTable.kmdNotifyProperties)); + + uint32_t hwTag = 9; + uint32_t taskCountToWait = 10; + EXPECT_TRUE(taskCountToWait - hwTag < KmdNotifyConstants::minimumTaskCountDiffToCheckAcLine); + EXPECT_EQ(10u, KmdNotifyConstants::minimumTaskCountDiffToCheckAcLine); + + int64_t timeout = 0; + helper.obtainTimeoutParams(timeout, false, hwTag, taskCountToWait, 1); + + EXPECT_EQ(0u, helper.updateAcLineStatusCalled); +} + +TEST_F(KmdNotifyTests, givenTaskCountDiffGreaterThanMinimumToCheckAcLineAndDisabledKmdNotifyWhenObtainingTimeoutPropertiesThenCheck) { + localHwInfo.capabilityTable.kmdNotifyProperties.enableKmdNotify = false; + MockKmdNotifyHelper helper(&(localHwInfo.capabilityTable.kmdNotifyProperties)); + + uint32_t hwTag = 10; + uint32_t taskCountToWait = 21; + EXPECT_TRUE(taskCountToWait - hwTag > KmdNotifyConstants::minimumTaskCountDiffToCheckAcLine); + EXPECT_EQ(10u, KmdNotifyConstants::minimumTaskCountDiffToCheckAcLine); + + int64_t timeout = 0; + helper.obtainTimeoutParams(timeout, false, hwTag, taskCountToWait, 1); + + EXPECT_EQ(1u, helper.updateAcLineStatusCalled); +} + +TEST_F(KmdNotifyTests, givenTaskCountDiffGreaterThanMinimumToCheckAcLineAndEnabledKmdNotifyWhenObtainingTimeoutPropertiesThenDontCheck) { + localHwInfo.capabilityTable.kmdNotifyProperties.enableKmdNotify = true; + MockKmdNotifyHelper helper(&(localHwInfo.capabilityTable.kmdNotifyProperties)); + + uint32_t hwTag = 10; + uint32_t taskCountToWait = 21; + EXPECT_TRUE(taskCountToWait - hwTag > KmdNotifyConstants::minimumTaskCountDiffToCheckAcLine); + EXPECT_EQ(10u, KmdNotifyConstants::minimumTaskCountDiffToCheckAcLine); + + int64_t timeout = 0; + helper.obtainTimeoutParams(timeout, false, hwTag, taskCountToWait, 1); + + EXPECT_EQ(0u, helper.updateAcLineStatusCalled); +} + +TEST_F(KmdNotifyTests, givenDisabledKmdNotifyMechanismWhenAcLineIsDisconnectedThenForceEnableTimeout) { + localHwInfo.capabilityTable.kmdNotifyProperties.enableKmdNotify = false; + MockKmdNotifyHelper helper(&(localHwInfo.capabilityTable.kmdNotifyProperties)); + helper.acLineConnected = false; + + int64_t timeout = 0; + bool timeoutEnabled = helper.obtainTimeoutParams(timeout, false, 1, 2, 2); + + EXPECT_TRUE(timeoutEnabled); + EXPECT_EQ(KmdNotifyConstants::timeoutInMicrosecondsForDisconnectedAcLine, timeout); + EXPECT_EQ(10000, KmdNotifyConstants::timeoutInMicrosecondsForDisconnectedAcLine); +} + +TEST_F(KmdNotifyTests, givenEnabledKmdNotifyMechanismWhenAcLineIsDisconnectedThenDontChangeTimeoutValue) { + localHwInfo.capabilityTable.kmdNotifyProperties.enableKmdNotify = true; + localHwInfo.capabilityTable.kmdNotifyProperties.delayKmdNotifyMicroseconds = 5; + MockKmdNotifyHelper helper(&(localHwInfo.capabilityTable.kmdNotifyProperties)); + helper.acLineConnected = false; + + int64_t timeout = 0; + bool timeoutEnabled = helper.obtainTimeoutParams(timeout, false, 1, 2, 2); + + EXPECT_TRUE(timeoutEnabled); + EXPECT_EQ(localHwInfo.capabilityTable.kmdNotifyProperties.delayKmdNotifyMicroseconds, timeout); +} + +TEST_F(KmdNotifyTests, givenDisabledKmdNotifyMechanismAndFlushStampIsZeroWhenAcLineIsDisconnectedThenDontForceEnableTimeout) { + localHwInfo.capabilityTable.kmdNotifyProperties.enableKmdNotify = false; + MockKmdNotifyHelper helper(&(localHwInfo.capabilityTable.kmdNotifyProperties)); + helper.acLineConnected = false; + + int64_t timeout = 0; + FlushStamp flushStampToWait = 0; + bool timeoutEnabled = helper.obtainTimeoutParams(timeout, false, 1, 2, flushStampToWait); + + EXPECT_FALSE(timeoutEnabled); } #if defined(__clang__) diff --git a/unit_tests/helpers/windows/kmd_notify_windows_tests.cpp b/unit_tests/helpers/windows/kmd_notify_windows_tests.cpp new file mode 100644 index 0000000000..853e3d4899 --- /dev/null +++ b/unit_tests/helpers/windows/kmd_notify_windows_tests.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2018, Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "runtime/helpers/kmd_notify_properties.h" +#include "runtime/helpers/options.h" +#include "runtime/os_interface/windows/sys_calls.h" + +#include "unit_tests/helpers/variable_backup.h" +#include "test.h" + +namespace OCLRT { + +namespace SysCalls { +extern BOOL systemPowerStatusRetVal; +extern BYTE systemPowerStatusACLineStatusOverride; +} // namespace SysCalls + +class MockKmdNotifyHelper : public KmdNotifyHelper { + public: + using KmdNotifyHelper::acLineConnected; + using KmdNotifyHelper::updateAcLineStatus; + + MockKmdNotifyHelper(const KmdNotifyProperties *newProperties) : KmdNotifyHelper(newProperties){}; +}; + +TEST(KmdNotifyWindowsTests, whenGetSystemPowerStatusReturnSuccessThenUpdateAcLineStatus) { + auto properties = &(platformDevices[0]->capabilityTable.kmdNotifyProperties); + MockKmdNotifyHelper helper(properties); + EXPECT_TRUE(helper.acLineConnected); + + VariableBackup systemPowerStatusRetValBkp(&SysCalls::systemPowerStatusRetVal); + VariableBackup systemPowerStatusACLineStatusOverrideBkp(&SysCalls::systemPowerStatusACLineStatusOverride); + systemPowerStatusRetValBkp = 1; + systemPowerStatusACLineStatusOverrideBkp = 0; + + helper.updateAcLineStatus(); + EXPECT_FALSE(helper.acLineConnected); + + systemPowerStatusACLineStatusOverrideBkp = 1; + + helper.updateAcLineStatus(); + EXPECT_TRUE(helper.acLineConnected); +} + +TEST(KmdNotifyWindowsTests, whenGetSystemPowerStatusReturnErrorThenDontUpdateAcLineStatus) { + auto properties = &(platformDevices[0]->capabilityTable.kmdNotifyProperties); + MockKmdNotifyHelper helper(properties); + EXPECT_TRUE(helper.acLineConnected); + + VariableBackup systemPowerStatusRetValBkp(&SysCalls::systemPowerStatusRetVal); + VariableBackup systemPowerStatusACLineStatusOverrideBkp(&SysCalls::systemPowerStatusACLineStatusOverride); + systemPowerStatusRetValBkp = 0; + systemPowerStatusACLineStatusOverrideBkp = 0; + + helper.updateAcLineStatus(); + EXPECT_TRUE(helper.acLineConnected); +} +} // namespace OCLRT diff --git a/unit_tests/libult/ult_command_stream_receiver.h b/unit_tests/libult/ult_command_stream_receiver.h index 46f0f0f8ed..74a5ee05d7 100644 --- a/unit_tests/libult/ult_command_stream_receiver.h +++ b/unit_tests/libult/ult_command_stream_receiver.h @@ -36,7 +36,6 @@ class UltCommandStreamReceiver : public CommandStreamReceiverHw { using BaseClass::dshState; using BaseClass::hwInfo; using BaseClass::iohState; - using BaseClass::lastWaitForCompletionTimestamp; using BaseClass::sshState; using BaseClass::CommandStreamReceiver::commandStream; using BaseClass::CommandStreamReceiver::disableL3Cache; diff --git a/unit_tests/os_interface/windows/sys_calls.cpp b/unit_tests/os_interface/windows/sys_calls.cpp index 0b97073b93..5f2a160bc1 100644 --- a/unit_tests/os_interface/windows/sys_calls.cpp +++ b/unit_tests/os_interface/windows/sys_calls.cpp @@ -28,6 +28,9 @@ namespace SysCalls { constexpr uintptr_t dummyHandle = static_cast(0x7); +BOOL systemPowerStatusRetVal = 1; +BYTE systemPowerStatusACLineStatusOverride = 1; + HANDLE createEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCSTR lpName) { return reinterpret_cast(dummyHandle); } @@ -36,6 +39,11 @@ BOOL closeHandle(HANDLE hObject) { return (reinterpret_cast(dummyHandle) == hObject) ? TRUE : FALSE; } +BOOL getSystemPowerStatus(LPSYSTEM_POWER_STATUS systemPowerStatusPtr) { + systemPowerStatusPtr->ACLineStatus = systemPowerStatusACLineStatusOverride; + return systemPowerStatusRetVal; +} + } // namespace SysCalls } // namespace OCLRT