summaryrefslogtreecommitdiffstats
path: root/src/core/hle/kernel/kernel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
-rw-r--r--src/core/hle/kernel/kernel.cpp69
1 files changed, 65 insertions, 4 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 1d0783bd3..4eb1d8703 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -3,13 +3,15 @@
// Refer to the license.txt file included.
#include <atomic>
+#include <functional>
#include <memory>
#include <mutex>
#include <utility>
#include "common/assert.h"
#include "common/logging/log.h"
-
+#include "core/arm/arm_interface.h"
+#include "core/arm/exclusive_monitor.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "core/core_timing_util.h"
@@ -17,9 +19,11 @@
#include "core/hle/kernel/errors.h"
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/physical_core.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/resource_limit.h"
#include "core/hle/kernel/scheduler.h"
+#include "core/hle/kernel/synchronization.h"
#include "core/hle/kernel/thread.h"
#include "core/hle/lock.h"
#include "core/hle/result.h"
@@ -51,10 +55,10 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_
if (thread->GetStatus() == ThreadStatus::WaitSynch ||
thread->GetStatus() == ThreadStatus::WaitHLEEvent) {
// Remove the thread from each of its waiting objects' waitlists
- for (const auto& object : thread->GetWaitObjects()) {
+ for (const auto& object : thread->GetSynchronizationObjects()) {
object->RemoveWaitingThread(thread);
}
- thread->ClearWaitObjects();
+ thread->ClearSynchronizationObjects();
// Invoke the wakeup callback before clearing the wait objects
if (thread->HasWakeupCallback()) {
@@ -93,11 +97,13 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_
}
struct KernelCore::Impl {
- explicit Impl(Core::System& system) : system{system}, global_scheduler{system} {}
+ explicit Impl(Core::System& system)
+ : system{system}, global_scheduler{system}, synchronization{system} {}
void Initialize(KernelCore& kernel) {
Shutdown();
+ InitializePhysicalCores();
InitializeSystemResourceLimit(kernel);
InitializeThreads();
InitializePreemption();
@@ -121,6 +127,21 @@ struct KernelCore::Impl {
global_scheduler.Shutdown();
named_ports.clear();
+
+ for (auto& core : cores) {
+ core.Shutdown();
+ }
+ cores.clear();
+
+ exclusive_monitor.reset();
+ }
+
+ void InitializePhysicalCores() {
+ exclusive_monitor =
+ Core::MakeExclusiveMonitor(system.Memory(), global_scheduler.CpuCoresCount());
+ for (std::size_t i = 0; i < global_scheduler.CpuCoresCount(); i++) {
+ cores.emplace_back(system, i, *exclusive_monitor);
+ }
}
// Creates the default system resource limit
@@ -172,6 +193,7 @@ struct KernelCore::Impl {
std::vector<std::shared_ptr<Process>> process_list;
Process* current_process = nullptr;
Kernel::GlobalScheduler global_scheduler;
+ Kernel::Synchronization synchronization;
std::shared_ptr<ResourceLimit> system_resource_limit;
@@ -186,6 +208,9 @@ struct KernelCore::Impl {
/// the ConnectToPort SVC.
NamedPortTable named_ports;
+ std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor;
+ std::vector<Kernel::PhysicalCore> cores;
+
// System context
Core::System& system;
};
@@ -240,6 +265,42 @@ const Kernel::GlobalScheduler& KernelCore::GlobalScheduler() const {
return impl->global_scheduler;
}
+Kernel::PhysicalCore& KernelCore::PhysicalCore(std::size_t id) {
+ return impl->cores[id];
+}
+
+const Kernel::PhysicalCore& KernelCore::PhysicalCore(std::size_t id) const {
+ return impl->cores[id];
+}
+
+Kernel::Synchronization& KernelCore::Synchronization() {
+ return impl->synchronization;
+}
+
+const Kernel::Synchronization& KernelCore::Synchronization() const {
+ return impl->synchronization;
+}
+
+Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() {
+ return *impl->exclusive_monitor;
+}
+
+const Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() const {
+ return *impl->exclusive_monitor;
+}
+
+void KernelCore::InvalidateAllInstructionCaches() {
+ for (std::size_t i = 0; i < impl->global_scheduler.CpuCoresCount(); i++) {
+ PhysicalCore(i).ArmInterface().ClearInstructionCache();
+ }
+}
+
+void KernelCore::PrepareReschedule(std::size_t id) {
+ if (id < impl->global_scheduler.CpuCoresCount()) {
+ impl->cores[id].Stop();
+ }
+}
+
void KernelCore::AddNamedPort(std::string name, std::shared_ptr<ClientPort> port) {
impl->named_ports.emplace(std::move(name), std::move(port));
}