summaryrefslogtreecommitdiffstats
path: root/src/core/hle/kernel/k_address_arbiter.h
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2020-12-30 08:18:06 +0100
committerbunnei <bunneidev@gmail.com>2021-01-11 23:23:16 +0100
commit952d1ac4879b8c597acbe23dcb58cc69d68a84e7 (patch)
tree0afa243761602828db7c26141ad2c6ceb80d6cf4 /src/core/hle/kernel/k_address_arbiter.h
parentcore: hle: kernel: Update KConditionVariable. (diff)
downloadyuzu-952d1ac4879b8c597acbe23dcb58cc69d68a84e7.tar
yuzu-952d1ac4879b8c597acbe23dcb58cc69d68a84e7.tar.gz
yuzu-952d1ac4879b8c597acbe23dcb58cc69d68a84e7.tar.bz2
yuzu-952d1ac4879b8c597acbe23dcb58cc69d68a84e7.tar.lz
yuzu-952d1ac4879b8c597acbe23dcb58cc69d68a84e7.tar.xz
yuzu-952d1ac4879b8c597acbe23dcb58cc69d68a84e7.tar.zst
yuzu-952d1ac4879b8c597acbe23dcb58cc69d68a84e7.zip
Diffstat (limited to 'src/core/hle/kernel/k_address_arbiter.h')
-rw-r--r--src/core/hle/kernel/k_address_arbiter.h70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/core/hle/kernel/k_address_arbiter.h b/src/core/hle/kernel/k_address_arbiter.h
new file mode 100644
index 000000000..8d379b524
--- /dev/null
+++ b/src/core/hle/kernel/k_address_arbiter.h
@@ -0,0 +1,70 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "common/assert.h"
+#include "common/common_types.h"
+#include "core/hle/kernel/k_condition_variable.h"
+#include "core/hle/kernel/svc_types.h"
+
+union ResultCode;
+
+namespace Core {
+class System;
+}
+
+namespace Kernel {
+
+class KernelCore;
+
+class KAddressArbiter {
+public:
+ using ThreadTree = KConditionVariable::ThreadTree;
+
+ explicit KAddressArbiter(Core::System& system_);
+ ~KAddressArbiter();
+
+ [[nodiscard]] ResultCode SignalToAddress(VAddr addr, Svc::SignalType type, s32 value,
+ s32 count) {
+ switch (type) {
+ case Svc::SignalType::Signal:
+ return Signal(addr, count);
+ case Svc::SignalType::SignalAndIncrementIfEqual:
+ return SignalAndIncrementIfEqual(addr, value, count);
+ case Svc::SignalType::SignalAndModifyByWaitingCountIfEqual:
+ return SignalAndModifyByWaitingCountIfEqual(addr, value, count);
+ }
+ UNREACHABLE();
+ return RESULT_UNKNOWN;
+ }
+
+ [[nodiscard]] ResultCode WaitForAddress(VAddr addr, Svc::ArbitrationType type, s32 value,
+ s64 timeout) {
+ switch (type) {
+ case Svc::ArbitrationType::WaitIfLessThan:
+ return WaitIfLessThan(addr, value, false, timeout);
+ case Svc::ArbitrationType::DecrementAndWaitIfLessThan:
+ return WaitIfLessThan(addr, value, true, timeout);
+ case Svc::ArbitrationType::WaitIfEqual:
+ return WaitIfEqual(addr, value, timeout);
+ }
+ UNREACHABLE();
+ return RESULT_UNKNOWN;
+ }
+
+private:
+ [[nodiscard]] ResultCode Signal(VAddr addr, s32 count);
+ [[nodiscard]] ResultCode SignalAndIncrementIfEqual(VAddr addr, s32 value, s32 count);
+ [[nodiscard]] ResultCode SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32 value, s32 count);
+ [[nodiscard]] ResultCode WaitIfLessThan(VAddr addr, s32 value, bool decrement, s64 timeout);
+ [[nodiscard]] ResultCode WaitIfEqual(VAddr addr, s32 value, s64 timeout);
+
+ ThreadTree thread_tree;
+
+ Core::System& system;
+ KernelCore& kernel;
+};
+
+} // namespace Kernel