set,poll event flag

This commit is contained in:
georgemoralis 2024-05-28 15:13:56 +03:00
parent 1dfa91b638
commit 4d5e9d1da4
3 changed files with 72 additions and 3 deletions

View File

@ -72,13 +72,60 @@ int PS4_SYSV_ABI sceKernelCancelEventFlag(OrbisKernelEventFlag ef, u64 setPatter
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceKernelSetEventFlag(OrbisKernelEventFlag ef, u64 bitPattern) { int PS4_SYSV_ABI sceKernelSetEventFlag(OrbisKernelEventFlag ef, u64 bitPattern) {
LOG_ERROR(Kernel_Event, "(STUBBED) called"); LOG_TRACE(Kernel_Event, "called");
if (ef == nullptr) {
return ORBIS_KERNEL_ERROR_ESRCH;
}
ef->Set(bitPattern);
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceKernelPollEventFlag(OrbisKernelEventFlag ef, u64 bitPattern, u32 waitMode, int PS4_SYSV_ABI sceKernelPollEventFlag(OrbisKernelEventFlag ef, u64 bitPattern, u32 waitMode,
u64* pResultPat) { u64* pResultPat) {
LOG_ERROR(Kernel_Event, "(STUBBED) called"); LOG_INFO(Kernel_Event, "called bitPattern = {:#x} waitMode = {:#x}", bitPattern, waitMode);
return ORBIS_OK;
if (ef == nullptr) {
return ORBIS_KERNEL_ERROR_ESRCH;
}
if (bitPattern == 0) {
return ORBIS_KERNEL_ERROR_EINVAL;
}
EventFlagInternal::WaitMode wait = EventFlagInternal::WaitMode::And;
EventFlagInternal::ClearMode clear = EventFlagInternal::ClearMode::None;
switch (waitMode & 0xf) {
case 0x01:
wait = EventFlagInternal::WaitMode::And;
break;
case 0x02:
wait = EventFlagInternal::WaitMode::Or;
break;
default:
UNREACHABLE();
}
switch (waitMode & 0xf0) {
case 0x00:
clear = EventFlagInternal::ClearMode::None;
break;
case 0x10:
clear = EventFlagInternal::ClearMode::All;
break;
case 0x20:
clear = EventFlagInternal::ClearMode::Bits;
break;
default:
UNREACHABLE();
}
auto result = ef->Poll(bitPattern, wait, clear, pResultPat);
if (result != ORBIS_OK) {
LOG_ERROR(Kernel_Event, "returned {}", result);
}
return result;
} }
int PS4_SYSV_ABI sceKernelWaitEventFlag(OrbisKernelEventFlag ef, u64 bitPattern, u32 waitMode, int PS4_SYSV_ABI sceKernelWaitEventFlag(OrbisKernelEventFlag ef, u64 bitPattern, u32 waitMode,
u64* pResultPat, OrbisKernelUseconds* pTimeout) { u64* pResultPat, OrbisKernelUseconds* pTimeout) {

View File

@ -70,4 +70,24 @@ int EventFlagInternal::Wait(u64 bits, WaitMode wait_mode, ClearMode clear_mode,
return ORBIS_OK; return ORBIS_OK;
} }
int EventFlagInternal::Poll(u64 bits, WaitMode wait_mode, ClearMode clear_mode, u64* result) {
u32 micros = 0;
return Wait(bits, wait_mode, clear_mode, result, &micros);
}
void EventFlagInternal::Set(u64 bits) {
std::unique_lock lock{m_mutex};
while (m_status != Status::Set) {
m_mutex.unlock();
std::this_thread::sleep_for(std::chrono::microseconds(10));
m_mutex.lock();
}
m_bits |= bits;
m_cond_var.notify_all();
}
} // namespace Libraries::Kernel } // namespace Libraries::Kernel

View File

@ -18,6 +18,8 @@ public:
: m_name(name), m_single_thread(single), m_fifo(fifo), m_bits(bits){}; : m_name(name), m_single_thread(single), m_fifo(fifo), m_bits(bits){};
int Wait(u64 bits, WaitMode wait_mode, ClearMode clear_mode, u64* result, u32* ptr_micros); int Wait(u64 bits, WaitMode wait_mode, ClearMode clear_mode, u64* result, u32* ptr_micros);
int Poll(u64 bits, WaitMode wait_mode, ClearMode clear_mode, u64* result);
void Set(u64 bits);
private: private:
enum class Status { Set, Canceled, Deleted }; enum class Status { Set, Canceled, Deleted };