2021-03-31 02:11:00 +08:00
|
|
|
/*
|
2024-01-18 19:39:39 +08:00
|
|
|
* Copyright (C) 2021-2024 Intel Corporation
|
2021-03-31 02:11:00 +08:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: MIT
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
2022-11-22 21:53:59 +08:00
|
|
|
#include "shared/source/command_stream/task_count_helper.h"
|
2021-03-31 02:11:00 +08:00
|
|
|
#include "shared/source/utilities/cpuintrinsics.h"
|
|
|
|
|
|
|
|
#include <cstdint>
|
2021-12-02 00:37:46 +08:00
|
|
|
#include <functional>
|
2021-03-31 02:11:00 +08:00
|
|
|
#include <thread>
|
|
|
|
|
|
|
|
namespace NEO {
|
|
|
|
|
|
|
|
namespace WaitUtils {
|
|
|
|
|
2021-04-01 20:22:47 +08:00
|
|
|
constexpr uint32_t defaultWaitCount = 1u;
|
2023-12-14 21:12:20 +08:00
|
|
|
|
2024-01-18 19:39:39 +08:00
|
|
|
extern uint64_t waitpkgCounterValue;
|
|
|
|
extern uint32_t waitpkgControlValue;
|
2021-03-31 02:11:00 +08:00
|
|
|
extern uint32_t waitCount;
|
2023-12-14 21:12:20 +08:00
|
|
|
extern bool waitpkgSupport;
|
|
|
|
extern bool waitpkgUse;
|
2021-03-31 02:11:00 +08:00
|
|
|
|
2024-01-18 19:39:39 +08:00
|
|
|
inline bool monitorWait(volatile void const *monitorAddress, uint64_t counterModifier) {
|
|
|
|
uint64_t currentCounter = CpuIntrinsics::rdtsc();
|
|
|
|
currentCounter += (waitpkgCounterValue + counterModifier);
|
|
|
|
|
|
|
|
CpuIntrinsics::umonitor(const_cast<void *>(monitorAddress));
|
|
|
|
bool result = CpuIntrinsics::umwait(waitpkgControlValue, currentCounter) == 0;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2021-12-02 00:37:46 +08:00
|
|
|
template <typename T>
|
|
|
|
inline bool waitFunctionWithPredicate(volatile T const *pollAddress, T expectedValue, std::function<bool(T, T)> predicate) {
|
2021-03-31 02:11:00 +08:00
|
|
|
for (uint32_t i = 0; i < waitCount; i++) {
|
|
|
|
CpuIntrinsics::pause();
|
|
|
|
}
|
|
|
|
if (pollAddress != nullptr) {
|
2021-12-02 00:37:46 +08:00
|
|
|
if (predicate(*pollAddress, expectedValue)) {
|
2021-03-31 02:11:00 +08:00
|
|
|
return true;
|
|
|
|
}
|
2024-01-18 19:39:39 +08:00
|
|
|
if (waitpkgUse) {
|
|
|
|
if (monitorWait(pollAddress, 0)) {
|
|
|
|
if (predicate(*pollAddress, expectedValue)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-03-31 02:11:00 +08:00
|
|
|
}
|
|
|
|
std::this_thread::yield();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-11-22 21:53:59 +08:00
|
|
|
inline bool waitFunction(volatile TagAddressType *pollAddress, TaskCountType expectedValue) {
|
|
|
|
return waitFunctionWithPredicate<TaskCountType>(pollAddress, expectedValue, std::greater_equal<TaskCountType>());
|
2021-12-02 00:37:46 +08:00
|
|
|
}
|
|
|
|
|
2021-03-31 02:11:00 +08:00
|
|
|
void init();
|
|
|
|
} // namespace WaitUtils
|
|
|
|
|
|
|
|
} // namespace NEO
|