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;
}