kernel: event_queue: initial `sceKernelAddHRTimerEvent` added
This commit is contained in:
parent
a5d22b8151
commit
53dd407ae3
|
@ -8,15 +8,19 @@ namespace Libraries::Kernel {
|
|||
|
||||
EqueueInternal::~EqueueInternal() = default;
|
||||
|
||||
int EqueueInternal::addEvent(const EqueueEvent& event) {
|
||||
int EqueueInternal::addEvent(EqueueEvent& event) {
|
||||
std::scoped_lock lock{m_mutex};
|
||||
|
||||
ASSERT(!event.IsTriggered());
|
||||
const auto start_clock = std::chrono::high_resolution_clock::now();
|
||||
event.filter.added_time_us =
|
||||
std::chrono::time_point_cast<std::chrono::microseconds>(start_clock);
|
||||
|
||||
const auto& it = std::ranges::find(m_events, event);
|
||||
ASSERT(it == m_events.cend()); // TODO: update event if found
|
||||
|
||||
if (it != m_events.cend()) {
|
||||
*it = event;
|
||||
} else {
|
||||
m_events.push_back(event);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ struct SceKernelEvent {
|
|||
|
||||
struct Filter {
|
||||
void* data = nullptr;
|
||||
std::chrono::time_point<std::chrono::steady_clock, std::chrono::microseconds> added_time_us;
|
||||
};
|
||||
|
||||
struct EqueueEvent {
|
||||
|
@ -89,6 +90,15 @@ struct EqueueEvent {
|
|||
}
|
||||
|
||||
bool IsTriggered() const {
|
||||
if (event.filter == Kernel::EVFILT_HRTIMER) {
|
||||
// For HR timers we don't want to waste time on spawning waiters. Instead, we will check
|
||||
// for time out condition every time caller fetches the event status.
|
||||
const auto now_clock = std::chrono::high_resolution_clock::now();
|
||||
const auto now_time_us =
|
||||
std::chrono::time_point_cast<std::chrono::microseconds>(now_clock);
|
||||
const auto delta = (now_time_us - filter.added_time_us).count();
|
||||
return (s64(event.data) - delta) <= 0;
|
||||
}
|
||||
return is_triggered;
|
||||
}
|
||||
|
||||
|
|
|
@ -113,6 +113,28 @@ int PS4_SYSV_ABI sceKernelAddUserEventEdge(SceKernelEqueue eq, int id) {
|
|||
return eq->addEvent(event);
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceKernelAddHRTimerEvent(SceKernelEqueue eq, int id, timespec* ts, void* udata) {
|
||||
if (eq == nullptr) {
|
||||
return ORBIS_KERNEL_ERROR_EBADF;
|
||||
}
|
||||
|
||||
if (ts->tv_sec > 100 || ts->tv_nsec < 100'000) {
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
ASSERT(ts->tv_nsec > 1000); // assume 1us granularity
|
||||
const auto total_us = ts->tv_sec * 1000'000 + ts->tv_nsec / 1000;
|
||||
|
||||
Kernel::EqueueEvent event{};
|
||||
event.event.ident = id;
|
||||
event.event.filter = Kernel::EVFILT_HRTIMER;
|
||||
event.event.flags = 0x11;
|
||||
event.event.fflags = 0;
|
||||
event.event.data = total_us;
|
||||
event.event.udata = udata;
|
||||
|
||||
return eq->addEvent(event);
|
||||
}
|
||||
|
||||
void* PS4_SYSV_ABI sceKernelGetEventUserData(const SceKernelEvent* ev) {
|
||||
if (!ev) {
|
||||
return nullptr;
|
||||
|
|
|
@ -19,5 +19,6 @@ int PS4_SYSV_ABI sceKernelTriggerUserEvent(SceKernelEqueue eq, int id, void* uda
|
|||
int PS4_SYSV_ABI sceKernelDeleteUserEvent(SceKernelEqueue eq, int id);
|
||||
int PS4_SYSV_ABI sceKernelAddUserEvent(SceKernelEqueue eq, int id);
|
||||
int PS4_SYSV_ABI sceKernelAddUserEventEdge(SceKernelEqueue eq, int id);
|
||||
s32 PS4_SYSV_ABI sceKernelAddHRTimerEvent(SceKernelEqueue eq, int id, timespec* ts, void* udata);
|
||||
|
||||
} // namespace Libraries::Kernel
|
||||
|
|
|
@ -324,6 +324,7 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) {
|
|||
LIB_FUNCTION("vz+pg2zdopI", "libkernel", 1, "libkernel", 1, 1, sceKernelGetEventUserData);
|
||||
LIB_FUNCTION("4R6-OvI2cEA", "libkernel", 1, "libkernel", 1, 1, sceKernelAddUserEvent);
|
||||
LIB_FUNCTION("WDszmSbWuDk", "libkernel", 1, "libkernel", 1, 1, sceKernelAddUserEventEdge);
|
||||
LIB_FUNCTION("R74tt43xP6k", "libkernel", 1, "libkernel", 1, 1, sceKernelAddHRTimerEvent);
|
||||
LIB_FUNCTION("F6e0kwo4cnk", "libkernel", 1, "libkernel", 1, 1, sceKernelTriggerUserEvent);
|
||||
LIB_FUNCTION("LJDwdSNTnDg", "libkernel", 1, "libkernel", 1, 1, sceKernelDeleteUserEvent);
|
||||
|
||||
|
|
Loading…
Reference in New Issue