summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/core.cpp2
-rw-r--r--src/core/hle/kernel/address_arbiter.cpp38
-rw-r--r--src/core/hle/kernel/address_arbiter.h16
-rw-r--r--src/core/hle/kernel/kernel.cpp12
-rw-r--r--src/core/hle/kernel/kernel.h6
-rw-r--r--src/core/hle/kernel/process.cpp9
-rw-r--r--src/core/hle/kernel/process.h22
-rw-r--r--src/core/hle/kernel/svc.cpp39
-rw-r--r--src/tests/core/arm/arm_test_common.cpp2
9 files changed, 81 insertions, 65 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp
index eba2177d1..89b3fb418 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -116,7 +116,7 @@ struct System::Impl {
116 if (web_browser == nullptr) 116 if (web_browser == nullptr)
117 web_browser = std::make_unique<Core::Frontend::DefaultWebBrowserApplet>(); 117 web_browser = std::make_unique<Core::Frontend::DefaultWebBrowserApplet>();
118 118
119 auto main_process = Kernel::Process::Create(kernel, "main"); 119 auto main_process = Kernel::Process::Create(system, "main");
120 kernel.MakeCurrentProcess(main_process.get()); 120 kernel.MakeCurrentProcess(main_process.get());
121 121
122 telemetry_session = std::make_unique<Core::TelemetrySession>(); 122 telemetry_session = std::make_unique<Core::TelemetrySession>();
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp
index 9780a7849..352190da8 100644
--- a/src/core/hle/kernel/address_arbiter.cpp
+++ b/src/core/hle/kernel/address_arbiter.cpp
@@ -42,7 +42,21 @@ void WakeThreads(const std::vector<SharedPtr<Thread>>& waiting_threads, s32 num_
42AddressArbiter::AddressArbiter(Core::System& system) : system{system} {} 42AddressArbiter::AddressArbiter(Core::System& system) : system{system} {}
43AddressArbiter::~AddressArbiter() = default; 43AddressArbiter::~AddressArbiter() = default;
44 44
45ResultCode AddressArbiter::SignalToAddress(VAddr address, s32 num_to_wake) { 45ResultCode AddressArbiter::SignalToAddress(VAddr address, SignalType type, s32 value,
46 s32 num_to_wake) {
47 switch (type) {
48 case SignalType::Signal:
49 return SignalToAddressOnly(address, num_to_wake);
50 case SignalType::IncrementAndSignalIfEqual:
51 return IncrementAndSignalToAddressIfEqual(address, value, num_to_wake);
52 case SignalType::ModifyByWaitingCountAndSignalIfEqual:
53 return ModifyByWaitingCountAndSignalToAddressIfEqual(address, value, num_to_wake);
54 default:
55 return ERR_INVALID_ENUM_VALUE;
56 }
57}
58
59ResultCode AddressArbiter::SignalToAddressOnly(VAddr address, s32 num_to_wake) {
46 const std::vector<SharedPtr<Thread>> waiting_threads = GetThreadsWaitingOnAddress(address); 60 const std::vector<SharedPtr<Thread>> waiting_threads = GetThreadsWaitingOnAddress(address);
47 WakeThreads(waiting_threads, num_to_wake); 61 WakeThreads(waiting_threads, num_to_wake);
48 return RESULT_SUCCESS; 62 return RESULT_SUCCESS;
@@ -60,7 +74,7 @@ ResultCode AddressArbiter::IncrementAndSignalToAddressIfEqual(VAddr address, s32
60 } 74 }
61 75
62 Memory::Write32(address, static_cast<u32>(value + 1)); 76 Memory::Write32(address, static_cast<u32>(value + 1));
63 return SignalToAddress(address, num_to_wake); 77 return SignalToAddressOnly(address, num_to_wake);
64} 78}
65 79
66ResultCode AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value, 80ResultCode AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value,
@@ -92,6 +106,20 @@ ResultCode AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr a
92 return RESULT_SUCCESS; 106 return RESULT_SUCCESS;
93} 107}
94 108
109ResultCode AddressArbiter::WaitForAddress(VAddr address, ArbitrationType type, s32 value,
110 s64 timeout_ns) {
111 switch (type) {
112 case ArbitrationType::WaitIfLessThan:
113 return WaitForAddressIfLessThan(address, value, timeout_ns, false);
114 case ArbitrationType::DecrementAndWaitIfLessThan:
115 return WaitForAddressIfLessThan(address, value, timeout_ns, true);
116 case ArbitrationType::WaitIfEqual:
117 return WaitForAddressIfEqual(address, value, timeout_ns);
118 default:
119 return ERR_INVALID_ENUM_VALUE;
120 }
121}
122
95ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout, 123ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s64 timeout,
96 bool should_decrement) { 124 bool should_decrement) {
97 // Ensure that we can read the address. 125 // Ensure that we can read the address.
@@ -113,7 +141,7 @@ ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s6
113 return RESULT_TIMEOUT; 141 return RESULT_TIMEOUT;
114 } 142 }
115 143
116 return WaitForAddress(address, timeout); 144 return WaitForAddressImpl(address, timeout);
117} 145}
118 146
119ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout) { 147ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout) {
@@ -130,10 +158,10 @@ ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 t
130 return RESULT_TIMEOUT; 158 return RESULT_TIMEOUT;
131 } 159 }
132 160
133 return WaitForAddress(address, timeout); 161 return WaitForAddressImpl(address, timeout);
134} 162}
135 163
136ResultCode AddressArbiter::WaitForAddress(VAddr address, s64 timeout) { 164ResultCode AddressArbiter::WaitForAddressImpl(VAddr address, s64 timeout) {
137 SharedPtr<Thread> current_thread = system.CurrentScheduler().GetCurrentThread(); 165 SharedPtr<Thread> current_thread = system.CurrentScheduler().GetCurrentThread();
138 current_thread->SetArbiterWaitAddress(address); 166 current_thread->SetArbiterWaitAddress(address);
139 current_thread->SetStatus(ThreadStatus::WaitArb); 167 current_thread->SetStatus(ThreadStatus::WaitArb);
diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h
index e0c36f2e3..ed0d0e69f 100644
--- a/src/core/hle/kernel/address_arbiter.h
+++ b/src/core/hle/kernel/address_arbiter.h
@@ -4,8 +4,10 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <vector>
8
7#include "common/common_types.h" 9#include "common/common_types.h"
8#include "core/hle/kernel/address_arbiter.h" 10#include "core/hle/kernel/object.h"
9 11
10union ResultCode; 12union ResultCode;
11 13
@@ -40,8 +42,15 @@ public:
40 AddressArbiter(AddressArbiter&&) = default; 42 AddressArbiter(AddressArbiter&&) = default;
41 AddressArbiter& operator=(AddressArbiter&&) = delete; 43 AddressArbiter& operator=(AddressArbiter&&) = delete;
42 44
45 /// Signals an address being waited on with a particular signaling type.
46 ResultCode SignalToAddress(VAddr address, SignalType type, s32 value, s32 num_to_wake);
47
48 /// Waits on an address with a particular arbitration type.
49 ResultCode WaitForAddress(VAddr address, ArbitrationType type, s32 value, s64 timeout_ns);
50
51private:
43 /// Signals an address being waited on. 52 /// Signals an address being waited on.
44 ResultCode SignalToAddress(VAddr address, s32 num_to_wake); 53 ResultCode SignalToAddressOnly(VAddr address, s32 num_to_wake);
45 54
46 /// Signals an address being waited on and increments its value if equal to the value argument. 55 /// Signals an address being waited on and increments its value if equal to the value argument.
47 ResultCode IncrementAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake); 56 ResultCode IncrementAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake);
@@ -59,9 +68,8 @@ public:
59 /// Waits on an address if the value passed is equal to the argument value. 68 /// Waits on an address if the value passed is equal to the argument value.
60 ResultCode WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout); 69 ResultCode WaitForAddressIfEqual(VAddr address, s32 value, s64 timeout);
61 70
62private:
63 // Waits on the given address with a timeout in nanoseconds 71 // Waits on the given address with a timeout in nanoseconds
64 ResultCode WaitForAddress(VAddr address, s64 timeout); 72 ResultCode WaitForAddressImpl(VAddr address, s64 timeout);
65 73
66 // Gets the threads waiting on an address. 74 // Gets the threads waiting on an address.
67 std::vector<SharedPtr<Thread>> GetThreadsWaitingOnAddress(VAddr address) const; 75 std::vector<SharedPtr<Thread>> GetThreadsWaitingOnAddress(VAddr address) const;
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 04ea9349e..4d224d01d 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -87,7 +87,7 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] int cycles_
87} 87}
88 88
89struct KernelCore::Impl { 89struct KernelCore::Impl {
90 explicit Impl(Core::System& system) : address_arbiter{system}, system{system} {} 90 explicit Impl(Core::System& system) : system{system} {}
91 91
92 void Initialize(KernelCore& kernel) { 92 void Initialize(KernelCore& kernel) {
93 Shutdown(); 93 Shutdown();
@@ -138,8 +138,6 @@ struct KernelCore::Impl {
138 std::vector<SharedPtr<Process>> process_list; 138 std::vector<SharedPtr<Process>> process_list;
139 Process* current_process = nullptr; 139 Process* current_process = nullptr;
140 140
141 Kernel::AddressArbiter address_arbiter;
142
143 SharedPtr<ResourceLimit> system_resource_limit; 141 SharedPtr<ResourceLimit> system_resource_limit;
144 142
145 Core::Timing::EventType* thread_wakeup_event_type = nullptr; 143 Core::Timing::EventType* thread_wakeup_event_type = nullptr;
@@ -192,14 +190,6 @@ const Process* KernelCore::CurrentProcess() const {
192 return impl->current_process; 190 return impl->current_process;
193} 191}
194 192
195AddressArbiter& KernelCore::AddressArbiter() {
196 return impl->address_arbiter;
197}
198
199const AddressArbiter& KernelCore::AddressArbiter() const {
200 return impl->address_arbiter;
201}
202
203void KernelCore::AddNamedPort(std::string name, SharedPtr<ClientPort> port) { 193void KernelCore::AddNamedPort(std::string name, SharedPtr<ClientPort> port) {
204 impl->named_ports.emplace(std::move(name), std::move(port)); 194 impl->named_ports.emplace(std::move(name), std::move(port));
205} 195}
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 4d292aca9..ff17ff865 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -75,12 +75,6 @@ public:
75 /// Retrieves a const pointer to the current process. 75 /// Retrieves a const pointer to the current process.
76 const Process* CurrentProcess() const; 76 const Process* CurrentProcess() const;
77 77
78 /// Provides a reference to the kernel's address arbiter.
79 Kernel::AddressArbiter& AddressArbiter();
80
81 /// Provides a const reference to the kernel's address arbiter.
82 const Kernel::AddressArbiter& AddressArbiter() const;
83
84 /// Adds a port to the named port table 78 /// Adds a port to the named port table
85 void AddNamedPort(std::string name, SharedPtr<ClientPort> port); 79 void AddNamedPort(std::string name, SharedPtr<ClientPort> port);
86 80
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index 8009150e0..7e8ba978c 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -53,9 +53,10 @@ void SetupMainThread(Process& owner_process, KernelCore& kernel, VAddr entry_poi
53CodeSet::CodeSet() = default; 53CodeSet::CodeSet() = default;
54CodeSet::~CodeSet() = default; 54CodeSet::~CodeSet() = default;
55 55
56SharedPtr<Process> Process::Create(KernelCore& kernel, std::string&& name) { 56SharedPtr<Process> Process::Create(Core::System& system, std::string&& name) {
57 SharedPtr<Process> process(new Process(kernel)); 57 auto& kernel = system.Kernel();
58 58
59 SharedPtr<Process> process(new Process(system));
59 process->name = std::move(name); 60 process->name = std::move(name);
60 process->resource_limit = kernel.GetSystemResourceLimit(); 61 process->resource_limit = kernel.GetSystemResourceLimit();
61 process->status = ProcessStatus::Created; 62 process->status = ProcessStatus::Created;
@@ -233,8 +234,8 @@ void Process::LoadModule(CodeSet module_, VAddr base_addr) {
233 Core::System::GetInstance().ArmInterface(3).ClearInstructionCache(); 234 Core::System::GetInstance().ArmInterface(3).ClearInstructionCache();
234} 235}
235 236
236Kernel::Process::Process(KernelCore& kernel) : WaitObject{kernel} {} 237Process::Process(Core::System& system) : WaitObject{system.Kernel()}, address_arbiter{system} {}
237Kernel::Process::~Process() {} 238Process::~Process() = default;
238 239
239void Process::Acquire(Thread* thread) { 240void Process::Acquire(Thread* thread) {
240 ASSERT_MSG(!ShouldWait(thread), "Object unavailable!"); 241 ASSERT_MSG(!ShouldWait(thread), "Object unavailable!");
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index dcc57ae9f..2a132c894 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -12,12 +12,17 @@
12#include <vector> 12#include <vector>
13#include <boost/container/static_vector.hpp> 13#include <boost/container/static_vector.hpp>
14#include "common/common_types.h" 14#include "common/common_types.h"
15#include "core/hle/kernel/address_arbiter.h"
15#include "core/hle/kernel/handle_table.h" 16#include "core/hle/kernel/handle_table.h"
16#include "core/hle/kernel/process_capability.h" 17#include "core/hle/kernel/process_capability.h"
17#include "core/hle/kernel/vm_manager.h" 18#include "core/hle/kernel/vm_manager.h"
18#include "core/hle/kernel/wait_object.h" 19#include "core/hle/kernel/wait_object.h"
19#include "core/hle/result.h" 20#include "core/hle/result.h"
20 21
22namespace Core {
23class System;
24}
25
21namespace FileSys { 26namespace FileSys {
22class ProgramMetadata; 27class ProgramMetadata;
23} 28}
@@ -116,7 +121,7 @@ public:
116 121
117 static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4; 122 static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4;
118 123
119 static SharedPtr<Process> Create(KernelCore& kernel, std::string&& name); 124 static SharedPtr<Process> Create(Core::System& system, std::string&& name);
120 125
121 std::string GetTypeName() const override { 126 std::string GetTypeName() const override {
122 return "Process"; 127 return "Process";
@@ -150,6 +155,16 @@ public:
150 return handle_table; 155 return handle_table;
151 } 156 }
152 157
158 /// Gets a reference to the process' address arbiter.
159 AddressArbiter& GetAddressArbiter() {
160 return address_arbiter;
161 }
162
163 /// Gets a const reference to the process' address arbiter.
164 const AddressArbiter& GetAddressArbiter() const {
165 return address_arbiter;
166 }
167
153 /// Gets the current status of the process 168 /// Gets the current status of the process
154 ProcessStatus GetStatus() const { 169 ProcessStatus GetStatus() const {
155 return status; 170 return status;
@@ -251,7 +266,7 @@ public:
251 void FreeTLSSlot(VAddr tls_address); 266 void FreeTLSSlot(VAddr tls_address);
252 267
253private: 268private:
254 explicit Process(KernelCore& kernel); 269 explicit Process(Core::System& kernel);
255 ~Process() override; 270 ~Process() override;
256 271
257 /// Checks if the specified thread should wait until this process is available. 272 /// Checks if the specified thread should wait until this process is available.
@@ -309,6 +324,9 @@ private:
309 /// Per-process handle table for storing created object handles in. 324 /// Per-process handle table for storing created object handles in.
310 HandleTable handle_table; 325 HandleTable handle_table;
311 326
327 /// Per-process address arbiter.
328 AddressArbiter address_arbiter;
329
312 /// Random values for svcGetInfo RandomEntropy 330 /// Random values for svcGetInfo RandomEntropy
313 std::array<u64, RANDOM_ENTROPY_SIZE> random_entropy; 331 std::array<u64, RANDOM_ENTROPY_SIZE> random_entropy;
314 332
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 7f5c0cc86..77d0e3d96 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -1479,21 +1479,10 @@ static ResultCode WaitForAddress(VAddr address, u32 type, s32 value, s64 timeout
1479 return ERR_INVALID_ADDRESS; 1479 return ERR_INVALID_ADDRESS;
1480 } 1480 }
1481 1481
1482 auto& address_arbiter = Core::System::GetInstance().Kernel().AddressArbiter(); 1482 const auto arbitration_type = static_cast<AddressArbiter::ArbitrationType>(type);
1483 switch (static_cast<AddressArbiter::ArbitrationType>(type)) { 1483 auto& address_arbiter =
1484 case AddressArbiter::ArbitrationType::WaitIfLessThan: 1484 Core::System::GetInstance().Kernel().CurrentProcess()->GetAddressArbiter();
1485 return address_arbiter.WaitForAddressIfLessThan(address, value, timeout, false); 1485 return address_arbiter.WaitForAddress(address, arbitration_type, value, timeout);
1486 case AddressArbiter::ArbitrationType::DecrementAndWaitIfLessThan:
1487 return address_arbiter.WaitForAddressIfLessThan(address, value, timeout, true);
1488 case AddressArbiter::ArbitrationType::WaitIfEqual:
1489 return address_arbiter.WaitForAddressIfEqual(address, value, timeout);
1490 default:
1491 LOG_ERROR(Kernel_SVC,
1492 "Invalid arbitration type, expected WaitIfLessThan, DecrementAndWaitIfLessThan "
1493 "or WaitIfEqual but got {}",
1494 type);
1495 return ERR_INVALID_ENUM_VALUE;
1496 }
1497} 1486}
1498 1487
1499// Signals to an address (via Address Arbiter) 1488// Signals to an address (via Address Arbiter)
@@ -1511,22 +1500,10 @@ static ResultCode SignalToAddress(VAddr address, u32 type, s32 value, s32 num_to
1511 return ERR_INVALID_ADDRESS; 1500 return ERR_INVALID_ADDRESS;
1512 } 1501 }
1513 1502
1514 auto& address_arbiter = Core::System::GetInstance().Kernel().AddressArbiter(); 1503 const auto signal_type = static_cast<AddressArbiter::SignalType>(type);
1515 switch (static_cast<AddressArbiter::SignalType>(type)) { 1504 auto& address_arbiter =
1516 case AddressArbiter::SignalType::Signal: 1505 Core::System::GetInstance().Kernel().CurrentProcess()->GetAddressArbiter();
1517 return address_arbiter.SignalToAddress(address, num_to_wake); 1506 return address_arbiter.SignalToAddress(address, signal_type, value, num_to_wake);
1518 case AddressArbiter::SignalType::IncrementAndSignalIfEqual:
1519 return address_arbiter.IncrementAndSignalToAddressIfEqual(address, value, num_to_wake);
1520 case AddressArbiter::SignalType::ModifyByWaitingCountAndSignalIfEqual:
1521 return address_arbiter.ModifyByWaitingCountAndSignalToAddressIfEqual(address, value,
1522 num_to_wake);
1523 default:
1524 LOG_ERROR(Kernel_SVC,
1525 "Invalid signal type, expected Signal, IncrementAndSignalIfEqual "
1526 "or ModifyByWaitingCountAndSignalIfEqual but got {}",
1527 type);
1528 return ERR_INVALID_ENUM_VALUE;
1529 }
1530} 1507}
1531 1508
1532/// This returns the total CPU ticks elapsed since the CPU was powered-on 1509/// This returns the total CPU ticks elapsed since the CPU was powered-on
diff --git a/src/tests/core/arm/arm_test_common.cpp b/src/tests/core/arm/arm_test_common.cpp
index ea27ef90d..6fe56833d 100644
--- a/src/tests/core/arm/arm_test_common.cpp
+++ b/src/tests/core/arm/arm_test_common.cpp
@@ -15,7 +15,7 @@ namespace ArmTests {
15TestEnvironment::TestEnvironment(bool mutable_memory_) 15TestEnvironment::TestEnvironment(bool mutable_memory_)
16 : mutable_memory(mutable_memory_), 16 : mutable_memory(mutable_memory_),
17 test_memory(std::make_shared<TestMemory>(this)), kernel{Core::System::GetInstance()} { 17 test_memory(std::make_shared<TestMemory>(this)), kernel{Core::System::GetInstance()} {
18 auto process = Kernel::Process::Create(kernel, ""); 18 auto process = Kernel::Process::Create(Core::System::GetInstance(), "");
19 kernel.MakeCurrentProcess(process.get()); 19 kernel.MakeCurrentProcess(process.get());
20 page_table = &process->VMManager().page_table; 20 page_table = &process->VMManager().page_table;
21 21