2024-02-23 22:32:32 +01:00
|
|
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
|
2024-04-14 16:09:51 +02:00
|
|
|
#include "common/assert.h"
|
2023-11-05 12:41:10 +01:00
|
|
|
#include "common/debug.h"
|
2024-04-13 23:35:48 +02:00
|
|
|
#include "core/libraries/kernel/event_queue.h"
|
2023-11-06 00:11:54 +01:00
|
|
|
|
2024-04-13 23:35:48 +02:00
|
|
|
namespace Libraries::Kernel {
|
2023-10-22 16:17:43 +02:00
|
|
|
|
2023-11-06 00:11:54 +01:00
|
|
|
EqueueInternal::~EqueueInternal() = default;
|
2023-09-05 13:28:52 +02:00
|
|
|
|
|
|
|
int EqueueInternal::addEvent(const EqueueEvent& event) {
|
2023-10-22 16:10:25 +02:00
|
|
|
std::scoped_lock lock{m_mutex};
|
2023-09-05 13:28:52 +02:00
|
|
|
|
2024-04-14 16:09:51 +02:00
|
|
|
ASSERT(m_events.empty());
|
|
|
|
ASSERT(!event.isTriggered);
|
|
|
|
|
2023-09-05 13:28:52 +02:00
|
|
|
// TODO check if event is already exists and return it. Currently we just add in m_events array
|
|
|
|
m_events.push_back(event);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-05-07 22:46:54 +02:00
|
|
|
int EqueueInternal::removeEvent(u64 id) {
|
|
|
|
const auto& event_q = std::find_if(m_events.cbegin(), m_events.cend(),
|
|
|
|
[id](auto& ev) { return ev.event.ident == id; });
|
|
|
|
ASSERT(event_q != m_events.cend());
|
|
|
|
m_events.erase(event_q);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-09-10 00:06:14 +02:00
|
|
|
int EqueueInternal::waitForEvents(SceKernelEvent* ev, int num, u32 micros) {
|
2023-10-22 16:10:25 +02:00
|
|
|
std::unique_lock lock{m_mutex};
|
2024-02-14 23:52:57 +01:00
|
|
|
int ret = 0;
|
2023-09-10 00:06:14 +02:00
|
|
|
|
2024-02-14 23:52:57 +01:00
|
|
|
const auto predicate = [&] {
|
|
|
|
ret = getTriggeredEvents(ev, num);
|
|
|
|
return ret > 0;
|
|
|
|
};
|
2024-04-14 18:57:58 +02:00
|
|
|
#ifndef _WIN64
|
2024-04-14 16:09:51 +02:00
|
|
|
char buf[128];
|
|
|
|
pthread_getname_np(pthread_self(), buf, 128);
|
|
|
|
fmt::print("Thread {} waiting for events (micros = {})\n", buf, micros);
|
2024-04-14 18:57:58 +02:00
|
|
|
#endif // !_WIN64
|
2024-02-14 23:52:57 +01:00
|
|
|
if (micros == 0) {
|
|
|
|
m_cond.wait(lock, predicate);
|
|
|
|
} else {
|
|
|
|
m_cond.wait_for(lock, std::chrono::microseconds(micros), predicate);
|
2023-09-10 00:06:14 +02:00
|
|
|
}
|
2024-04-14 16:09:51 +02:00
|
|
|
fmt::print("Wait done\n");
|
2024-02-14 23:52:57 +01:00
|
|
|
return ret;
|
2023-09-10 00:06:14 +02:00
|
|
|
}
|
|
|
|
|
2023-09-11 12:14:13 +02:00
|
|
|
bool EqueueInternal::triggerEvent(u64 ident, s16 filter, void* trigger_data) {
|
2023-10-22 16:10:25 +02:00
|
|
|
std::scoped_lock lock{m_mutex};
|
2023-09-11 12:14:13 +02:00
|
|
|
|
2024-04-14 16:09:51 +02:00
|
|
|
ASSERT(m_events.size() <= 1);
|
2023-09-11 12:14:13 +02:00
|
|
|
|
2024-04-14 16:09:51 +02:00
|
|
|
auto& event = m_events[0];
|
|
|
|
event.trigger(trigger_data);
|
2023-10-22 16:10:25 +02:00
|
|
|
m_cond.notify_one();
|
2023-09-11 12:14:13 +02:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2023-09-10 00:06:14 +02:00
|
|
|
int EqueueInternal::getTriggeredEvents(SceKernelEvent* ev, int num) {
|
|
|
|
int ret = 0;
|
|
|
|
|
2024-04-14 16:09:51 +02:00
|
|
|
ASSERT(m_events.size() <= 1);
|
2023-09-10 00:06:14 +02:00
|
|
|
auto& event = m_events[0];
|
|
|
|
|
|
|
|
if (event.isTriggered) {
|
|
|
|
ev[ret++] = event.event;
|
2024-04-14 16:09:51 +02:00
|
|
|
event.reset();
|
2023-09-10 00:06:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2024-04-13 23:35:48 +02:00
|
|
|
} // namespace Libraries::Kernel
|