diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index ff0a3243a6..01262ddd16 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -498,6 +498,8 @@ + + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 85234f20a7..fef8d76074 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -1831,6 +1831,12 @@ Utilities + + Utilities + + + Utilities + Utilities diff --git a/rpcs3/util/fifo_mutex.hpp b/rpcs3/util/fifo_mutex.hpp new file mode 100644 index 0000000000..37a18004c5 --- /dev/null +++ b/rpcs3/util/fifo_mutex.hpp @@ -0,0 +1,70 @@ +#pragma once + +#include "util/types.hpp" +#include "util/atomic.hpp" +#include + +// Mutex that tries to maintain the order of acquisition +class fifo_mutex +{ + // Low 8 bits are incremented on acquisition, high 8 bits are incremented on release + atomic_t m_value{0}; + +public: + constexpr fifo_mutex() noexcept = default; + + void lock() noexcept + { + const u16 val = m_value.fetch_op([](u16& val) + { + val = (val & 0xff00) | ((val + 1) & 0xff); + }); + + if (val >> 8 != (val & 0xff)) [[unlikely]] + { + // TODO: implement busy waiting along with moving to cpp file + m_value.wait(((val + 1) & 0xff) << 8, 0xff00); + } + } + + bool try_lock() noexcept + { + const u16 val = m_value.load(); + + if (val >> 8 == (val & 0xff)) + { + if (m_value.compare_and_swap(val, ((val + 1) & 0xff) | (val & 0xff00))) + { + return true; + } + } + + return false; + } + + void unlock() noexcept + { + const u16 val = m_value.add_fetch(0x100); + + if (val >> 8 != (val & 0xff)) + { + m_value.notify_one(); + } + } + + bool is_free() const noexcept + { + const u16 val = m_value.load(); + + return (val >> 8) == (val & 0xff); + } + + void lock_unlock() noexcept + { + if (!is_free()) + { + lock(); + unlock(); + } + } +}; diff --git a/rpcs3/util/slow_mutex.hpp b/rpcs3/util/slow_mutex.hpp index 8ff5f3678c..1dfdabd2ee 100644 --- a/rpcs3/util/slow_mutex.hpp +++ b/rpcs3/util/slow_mutex.hpp @@ -1,6 +1,7 @@ #pragma once -#include "atomic.hpp" +#include "util/types.hpp" +#include "util/atomic.hpp" #include "Utilities/StrFmt.h" #include @@ -79,7 +80,7 @@ public: } } - bool is_free() noexcept + bool is_free() const noexcept { return !m_value; }