diff --git a/src/core/libraries/kernel/event_flag/event_flag.cpp b/src/core/libraries/kernel/event_flag/event_flag.cpp index fffce0f7..659d3cd7 100644 --- a/src/core/libraries/kernel/event_flag/event_flag.cpp +++ b/src/core/libraries/kernel/event_flag/event_flag.cpp @@ -18,36 +18,44 @@ int PS4_SYSV_ABI sceKernelCreateEventFlag(OrbisKernelEventFlag* ef, const char* } if (pOptParam || !pName || attr > (ORBIS_KERNEL_EVF_ATTR_MULTI | ORBIS_KERNEL_EVF_ATTR_TH_PRIO)) { - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } if (strlen(pName) >= 32) { return ORBIS_KERNEL_ERROR_ENAMETOOLONG; } - bool single = true; - bool fifo = true; + EventFlagInternal::ThreadMode thread_mode = EventFlagInternal::ThreadMode::Single; + EventFlagInternal::QueueMode queue_mode = EventFlagInternal::QueueMode::Fifo; - switch (attr) { - case 0x10: - case 0x11: - single = true; - fifo = true; + switch (attr & 0xfu) { + case 0x01: + queue_mode = EventFlagInternal::QueueMode::Fifo; break; - case 0x20: - case 0x21: - single = false; - fifo = true; + case 0x02: + queue_mode = EventFlagInternal::QueueMode::ThreadPrio; break; - case 0x22: - single = false; - fifo = false; + case 0x00: break; default: UNREACHABLE(); } - *ef = new EventFlagInternal(std::string(pName), single, fifo, initPattern); + switch (attr & 0xf0) { + case 0x10: + thread_mode = EventFlagInternal::ThreadMode::Single; + break; + case 0x20: + thread_mode = EventFlagInternal::ThreadMode::Multi; + break; + default: + UNREACHABLE(); + } + + ASSERT_MSG(queue_mode == EventFlagInternal::QueueMode::Fifo, + "ThreadPriority attr is not supported!"); + + *ef = new EventFlagInternal(std::string(pName), thread_mode, queue_mode, initPattern); return ORBIS_OK; } int PS4_SYSV_ABI sceKernelDeleteEventFlag(OrbisKernelEventFlag ef) { diff --git a/src/core/libraries/kernel/event_flag/event_flag_obj.cpp b/src/core/libraries/kernel/event_flag/event_flag_obj.cpp index 069ae9dc..66f0d3d7 100644 --- a/src/core/libraries/kernel/event_flag/event_flag_obj.cpp +++ b/src/core/libraries/kernel/event_flag/event_flag_obj.cpp @@ -16,7 +16,7 @@ int EventFlagInternal::Wait(u64 bits, WaitMode wait_mode, ClearMode clear_mode, infinitely = false; } - if (m_single_thread && m_waiting_threads > 0) { + if (m_thread_mode == ThreadMode::Single && m_waiting_threads > 0) { return ORBIS_KERNEL_ERROR_EPERM; } diff --git a/src/core/libraries/kernel/event_flag/event_flag_obj.h b/src/core/libraries/kernel/event_flag/event_flag_obj.h index a4a85a8e..efeee088 100644 --- a/src/core/libraries/kernel/event_flag/event_flag_obj.h +++ b/src/core/libraries/kernel/event_flag/event_flag_obj.h @@ -14,8 +14,13 @@ public: enum class WaitMode { And, Or }; - EventFlagInternal(const std::string& name, bool single, bool fifo, uint64_t bits) - : m_name(name), m_single_thread(single), m_fifo(fifo), m_bits(bits){}; + enum class ThreadMode { Single, Multi }; + + enum class QueueMode { Fifo, ThreadPrio }; + + EventFlagInternal(const std::string& name, ThreadMode thread_mode, QueueMode queue_mode, + uint64_t bits) + : m_name(name), m_thread_mode(thread_mode), m_queue_mode(queue_mode), m_bits(bits){}; 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); @@ -29,8 +34,8 @@ private: Status m_status = Status::Set; int m_waiting_threads = 0; std::string m_name; - bool m_single_thread = false; - bool m_fifo = false; + ThreadMode m_thread_mode = ThreadMode::Single; + QueueMode m_queue_mode = QueueMode::Fifo; u64 m_bits = 0; }; } // namespace Libraries::Kernel \ No newline at end of file