summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hardware_properties.h31
-rw-r--r--src/core/hle/kernel/scheduler.cpp4
-rw-r--r--src/core/hle/kernel/server_session.cpp2
-rw-r--r--src/core/hle/kernel/svc.cpp2
-rw-r--r--src/core/hle/kernel/synchronization.cpp21
-rw-r--r--src/core/hle/kernel/synchronization.h14
6 files changed, 50 insertions, 24 deletions
diff --git a/src/core/hardware_properties.h b/src/core/hardware_properties.h
index 62cdf9ef0..947140efb 100644
--- a/src/core/hardware_properties.h
+++ b/src/core/hardware_properties.h
@@ -8,14 +8,6 @@
8 8
9namespace Core { 9namespace Core {
10 10
11union EmuThreadHandle {
12 u64 raw;
13 struct {
14 u32 host_handle;
15 u32 guest_handle;
16 };
17};
18
19namespace Hardware { 11namespace Hardware {
20 12
21// The below clock rate is based on Switch's clockspeed being widely known as 1.020GHz 13// The below clock rate is based on Switch's clockspeed being widely known as 1.020GHz
@@ -23,6 +15,29 @@ namespace Hardware {
23constexpr u64 BASE_CLOCK_RATE = 1019215872; // Switch cpu frequency is 1020MHz un/docked 15constexpr u64 BASE_CLOCK_RATE = 1019215872; // Switch cpu frequency is 1020MHz un/docked
24constexpr u64 CNTFREQ = 19200000; // Switch's hardware clock speed 16constexpr u64 CNTFREQ = 19200000; // Switch's hardware clock speed
25constexpr u32 NUM_CPU_CORES = 4; // Number of CPU Cores 17constexpr u32 NUM_CPU_CORES = 4; // Number of CPU Cores
18
26} // namespace Hardware 19} // namespace Hardware
27 20
21struct EmuThreadHandle {
22 u32 host_handle;
23 u32 guest_handle;
24
25 u64 GetRaw() const {
26 return (static_cast<u64>(host_handle) << 32) | guest_handle;
27 }
28
29 bool operator==(const EmuThreadHandle& rhs) const {
30 return std::tie(host_handle, guest_handle) == std::tie(rhs.host_handle, rhs.guest_handle);
31 }
32
33 bool operator!=(const EmuThreadHandle& rhs) const {
34 return !operator==(rhs);
35 }
36
37 static constexpr EmuThreadHandle InvalidHandle() {
38 constexpr u32 invalid_handle = 0xFFFFFFFF;
39 return {invalid_handle, invalid_handle};
40 }
41};
42
28} // namespace Core 43} // namespace Core
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp
index b5ffa5418..86f1421bf 100644
--- a/src/core/hle/kernel/scheduler.cpp
+++ b/src/core/hle/kernel/scheduler.cpp
@@ -125,7 +125,7 @@ bool GlobalScheduler::YieldThreadAndBalanceLoad(Thread* yielding_thread) {
125 scheduled_queue[core_id].yield(priority); 125 scheduled_queue[core_id].yield(priority);
126 126
127 std::array<Thread*, Core::Hardware::NUM_CPU_CORES> current_threads; 127 std::array<Thread*, Core::Hardware::NUM_CPU_CORES> current_threads;
128 for (u32 i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { 128 for (std::size_t i = 0; i < current_threads.size(); i++) {
129 current_threads[i] = scheduled_queue[i].empty() ? nullptr : scheduled_queue[i].front(); 129 current_threads[i] = scheduled_queue[i].empty() ? nullptr : scheduled_queue[i].front();
130 } 130 }
131 131
@@ -178,7 +178,7 @@ bool GlobalScheduler::YieldThreadAndWaitForLoadBalancing(Thread* yielding_thread
178 if (scheduled_queue[core_id].empty()) { 178 if (scheduled_queue[core_id].empty()) {
179 // Here, "current_threads" is calculated after the ""yield"", unlike yield -1 179 // Here, "current_threads" is calculated after the ""yield"", unlike yield -1
180 std::array<Thread*, Core::Hardware::NUM_CPU_CORES> current_threads; 180 std::array<Thread*, Core::Hardware::NUM_CPU_CORES> current_threads;
181 for (u32 i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { 181 for (std::size_t i = 0; i < current_threads.size(); i++) {
182 current_threads[i] = scheduled_queue[i].empty() ? nullptr : scheduled_queue[i].front(); 182 current_threads[i] = scheduled_queue[i].empty() ? nullptr : scheduled_queue[i].front();
183 } 183 }
184 for (auto& thread : suggested_queue[core_id]) { 184 for (auto& thread : suggested_queue[core_id]) {
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp
index ca98fd984..4604e35c5 100644
--- a/src/core/hle/kernel/server_session.cpp
+++ b/src/core/hle/kernel/server_session.cpp
@@ -57,7 +57,7 @@ bool ServerSession::IsSignaled() const {
57 } 57 }
58 58
59 // Wait if we have no pending requests, or if we're currently handling a request. 59 // Wait if we have no pending requests, or if we're currently handling a request.
60 return !(pending_requesting_threads.empty() || currently_handling != nullptr); 60 return !pending_requesting_threads.empty() && currently_handling == nullptr;
61} 61}
62 62
63void ServerSession::Acquire(Thread* thread) { 63void ServerSession::Acquire(Thread* thread) {
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 86c660cdf..fd91779a3 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -474,7 +474,7 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr
474 objects[i] = object; 474 objects[i] = object;
475 } 475 }
476 auto& synchronization = kernel.Synchronization(); 476 auto& synchronization = kernel.Synchronization();
477 auto [result, handle_result] = synchronization.WaitFor(objects, nano_seconds); 477 const auto [result, handle_result] = synchronization.WaitFor(objects, nano_seconds);
478 *index = handle_result; 478 *index = handle_result;
479 return result; 479 return result;
480} 480}
diff --git a/src/core/hle/kernel/synchronization.cpp b/src/core/hle/kernel/synchronization.cpp
index 25afc162f..dc37fad1a 100644
--- a/src/core/hle/kernel/synchronization.cpp
+++ b/src/core/hle/kernel/synchronization.cpp
@@ -4,6 +4,7 @@
4 4
5#include "core/core.h" 5#include "core/core.h"
6#include "core/hle/kernel/errors.h" 6#include "core/hle/kernel/errors.h"
7#include "core/hle/kernel/handle_table.h"
7#include "core/hle/kernel/kernel.h" 8#include "core/hle/kernel/kernel.h"
8#include "core/hle/kernel/scheduler.h" 9#include "core/hle/kernel/scheduler.h"
9#include "core/hle/kernel/synchronization.h" 10#include "core/hle/kernel/synchronization.h"
@@ -27,30 +28,30 @@ static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, std::shared_p
27 thread->SetWaitSynchronizationResult(RESULT_SUCCESS); 28 thread->SetWaitSynchronizationResult(RESULT_SUCCESS);
28 thread->SetWaitSynchronizationOutput(static_cast<u32>(index)); 29 thread->SetWaitSynchronizationOutput(static_cast<u32>(index));
29 return true; 30 return true;
30}; 31}
31 32
32Synchronization::Synchronization(Core::System& system) : system{system} {} 33Synchronization::Synchronization(Core::System& system) : system{system} {}
33 34
34void Synchronization::SignalObject(SynchronizationObject& obj) const { 35void Synchronization::SignalObject(SynchronizationObject& obj) const {
35 if (obj.IsSignaled()) { 36 if (obj.IsSignaled()) {
36 obj.WakeupAllWaitingThreads(); 37 obj.WakeupAllWaitingThreads();
37 }; 38 }
38} 39}
39 40
40std::pair<ResultCode, Handle> Synchronization::WaitFor( 41std::pair<ResultCode, Handle> Synchronization::WaitFor(
41 std::vector<std::shared_ptr<SynchronizationObject>>& sync_objects, s64 nano_seconds) { 42 std::vector<std::shared_ptr<SynchronizationObject>>& sync_objects, s64 nano_seconds) {
42 auto* const thread = system.CurrentScheduler().GetCurrentThread(); 43 auto* const thread = system.CurrentScheduler().GetCurrentThread();
43 // Find the first object that is acquirable in the provided list of objects 44 // Find the first object that is acquirable in the provided list of objects
44 auto itr = std::find_if(sync_objects.begin(), sync_objects.end(), 45 const auto itr = std::find_if(sync_objects.begin(), sync_objects.end(),
45 [thread](const std::shared_ptr<SynchronizationObject>& object) { 46 [thread](const std::shared_ptr<SynchronizationObject>& object) {
46 return object->IsSignaled(); 47 return object->IsSignaled();
47 }); 48 });
48 49
49 if (itr != sync_objects.end()) { 50 if (itr != sync_objects.end()) {
50 // We found a ready object, acquire it and set the result value 51 // We found a ready object, acquire it and set the result value
51 SynchronizationObject* object = itr->get(); 52 SynchronizationObject* object = itr->get();
52 object->Acquire(thread); 53 object->Acquire(thread);
53 u32 index = static_cast<s32>(std::distance(sync_objects.begin(), itr)); 54 const u32 index = static_cast<s32>(std::distance(sync_objects.begin(), itr));
54 return {RESULT_SUCCESS, index}; 55 return {RESULT_SUCCESS, index};
55 } 56 }
56 57
@@ -59,12 +60,12 @@ std::pair<ResultCode, Handle> Synchronization::WaitFor(
59 // If a timeout value of 0 was provided, just return the Timeout error code instead of 60 // If a timeout value of 0 was provided, just return the Timeout error code instead of
60 // suspending the thread. 61 // suspending the thread.
61 if (nano_seconds == 0) { 62 if (nano_seconds == 0) {
62 return {RESULT_TIMEOUT, 0}; 63 return {RESULT_TIMEOUT, InvalidHandle};
63 } 64 }
64 65
65 if (thread->IsSyncCancelled()) { 66 if (thread->IsSyncCancelled()) {
66 thread->SetSyncCancelled(false); 67 thread->SetSyncCancelled(false);
67 return {ERR_SYNCHRONIZATION_CANCELED, 0}; 68 return {ERR_SYNCHRONIZATION_CANCELED, InvalidHandle};
68 } 69 }
69 70
70 for (auto& object : sync_objects) { 71 for (auto& object : sync_objects) {
@@ -80,7 +81,7 @@ std::pair<ResultCode, Handle> Synchronization::WaitFor(
80 81
81 system.PrepareReschedule(thread->GetProcessorID()); 82 system.PrepareReschedule(thread->GetProcessorID());
82 83
83 return {RESULT_TIMEOUT, 0}; 84 return {RESULT_TIMEOUT, InvalidHandle};
84} 85}
85 86
86} // namespace Kernel 87} // namespace Kernel
diff --git a/src/core/hle/kernel/synchronization.h b/src/core/hle/kernel/synchronization.h
index 3417a9f13..379f4b1d3 100644
--- a/src/core/hle/kernel/synchronization.h
+++ b/src/core/hle/kernel/synchronization.h
@@ -6,6 +6,7 @@
6 6
7#include <memory> 7#include <memory>
8#include <utility> 8#include <utility>
9#include <vector>
9 10
10#include "core/hle/kernel/object.h" 11#include "core/hle/kernel/object.h"
11#include "core/hle/result.h" 12#include "core/hle/result.h"
@@ -16,15 +17,24 @@ class System;
16 17
17namespace Kernel { 18namespace Kernel {
18 19
19class KernelCore;
20class SynchronizationObject; 20class SynchronizationObject;
21 21
22/**
23 * The 'Synchronization' class is an interface for handling synchronization methods
24 * used by Synchronization objects and synchronization SVCs. This centralizes processing of
25 * such
26 */
22class Synchronization { 27class Synchronization {
23public: 28public:
24 Synchronization(Core::System& system); 29 explicit Synchronization(Core::System& system);
25 30
31 /// Signals a synchronization object, waking up all its waiting threads
26 void SignalObject(SynchronizationObject& obj) const; 32 void SignalObject(SynchronizationObject& obj) const;
27 33
34 /// Tries to see if waiting for any of the sync_objects is necessary, if not
35 /// it returns Success and the handle index of the signaled sync object. In
36 /// case not, the current thread will be locked and wait for nano_seconds or
37 /// for a synchronization object to signal.
28 std::pair<ResultCode, Handle> WaitFor( 38 std::pair<ResultCode, Handle> WaitFor(
29 std::vector<std::shared_ptr<SynchronizationObject>>& sync_objects, s64 nano_seconds); 39 std::vector<std::shared_ptr<SynchronizationObject>>& sync_objects, s64 nano_seconds);
30 40