kernel: Make the address arbiter instance per-process
Now that we have the address arbiter extracted to its own class, we can fix an innaccuracy with the kernel. Said inaccuracy being that there isn't only one address arbiter. Each process instance contains its own AddressArbiter instance in the actual kernel. This fixes that and gets rid of another long-standing issue that could arise when attempting to create more than one process.
This commit is contained in:
parent
b7f331afa3
commit
8e510d5afa
8 changed files with 35 additions and 28 deletions
|
@ -116,7 +116,7 @@ struct System::Impl {
|
||||||
if (web_browser == nullptr)
|
if (web_browser == nullptr)
|
||||||
web_browser = std::make_unique<Core::Frontend::DefaultWebBrowserApplet>();
|
web_browser = std::make_unique<Core::Frontend::DefaultWebBrowserApplet>();
|
||||||
|
|
||||||
auto main_process = Kernel::Process::Create(kernel, "main");
|
auto main_process = Kernel::Process::Create(system, "main");
|
||||||
kernel.MakeCurrentProcess(main_process.get());
|
kernel.MakeCurrentProcess(main_process.get());
|
||||||
|
|
||||||
telemetry_session = std::make_unique<Core::TelemetrySession>();
|
telemetry_session = std::make_unique<Core::TelemetrySession>();
|
||||||
|
|
|
@ -4,8 +4,10 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/hle/kernel/address_arbiter.h"
|
#include "core/hle/kernel/object.h"
|
||||||
|
|
||||||
union ResultCode;
|
union ResultCode;
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] int cycles_
|
||||||
}
|
}
|
||||||
|
|
||||||
struct KernelCore::Impl {
|
struct KernelCore::Impl {
|
||||||
explicit Impl(Core::System& system) : address_arbiter{system}, system{system} {}
|
explicit Impl(Core::System& system) : system{system} {}
|
||||||
|
|
||||||
void Initialize(KernelCore& kernel) {
|
void Initialize(KernelCore& kernel) {
|
||||||
Shutdown();
|
Shutdown();
|
||||||
|
@ -138,8 +138,6 @@ struct KernelCore::Impl {
|
||||||
std::vector<SharedPtr<Process>> process_list;
|
std::vector<SharedPtr<Process>> process_list;
|
||||||
Process* current_process = nullptr;
|
Process* current_process = nullptr;
|
||||||
|
|
||||||
Kernel::AddressArbiter address_arbiter;
|
|
||||||
|
|
||||||
SharedPtr<ResourceLimit> system_resource_limit;
|
SharedPtr<ResourceLimit> system_resource_limit;
|
||||||
|
|
||||||
Core::Timing::EventType* thread_wakeup_event_type = nullptr;
|
Core::Timing::EventType* thread_wakeup_event_type = nullptr;
|
||||||
|
@ -192,14 +190,6 @@ const Process* KernelCore::CurrentProcess() const {
|
||||||
return impl->current_process;
|
return impl->current_process;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddressArbiter& KernelCore::AddressArbiter() {
|
|
||||||
return impl->address_arbiter;
|
|
||||||
}
|
|
||||||
|
|
||||||
const AddressArbiter& KernelCore::AddressArbiter() const {
|
|
||||||
return impl->address_arbiter;
|
|
||||||
}
|
|
||||||
|
|
||||||
void KernelCore::AddNamedPort(std::string name, SharedPtr<ClientPort> port) {
|
void KernelCore::AddNamedPort(std::string name, SharedPtr<ClientPort> port) {
|
||||||
impl->named_ports.emplace(std::move(name), std::move(port));
|
impl->named_ports.emplace(std::move(name), std::move(port));
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,12 +75,6 @@ public:
|
||||||
/// Retrieves a const pointer to the current process.
|
/// Retrieves a const pointer to the current process.
|
||||||
const Process* CurrentProcess() const;
|
const Process* CurrentProcess() const;
|
||||||
|
|
||||||
/// Provides a reference to the kernel's address arbiter.
|
|
||||||
Kernel::AddressArbiter& AddressArbiter();
|
|
||||||
|
|
||||||
/// Provides a const reference to the kernel's address arbiter.
|
|
||||||
const Kernel::AddressArbiter& AddressArbiter() const;
|
|
||||||
|
|
||||||
/// Adds a port to the named port table
|
/// Adds a port to the named port table
|
||||||
void AddNamedPort(std::string name, SharedPtr<ClientPort> port);
|
void AddNamedPort(std::string name, SharedPtr<ClientPort> port);
|
||||||
|
|
||||||
|
|
|
@ -53,9 +53,10 @@ void SetupMainThread(Process& owner_process, KernelCore& kernel, VAddr entry_poi
|
||||||
CodeSet::CodeSet() = default;
|
CodeSet::CodeSet() = default;
|
||||||
CodeSet::~CodeSet() = default;
|
CodeSet::~CodeSet() = default;
|
||||||
|
|
||||||
SharedPtr<Process> Process::Create(KernelCore& kernel, std::string&& name) {
|
SharedPtr<Process> Process::Create(Core::System& system, std::string&& name) {
|
||||||
SharedPtr<Process> process(new Process(kernel));
|
auto& kernel = system.Kernel();
|
||||||
|
|
||||||
|
SharedPtr<Process> process(new Process(system));
|
||||||
process->name = std::move(name);
|
process->name = std::move(name);
|
||||||
process->resource_limit = kernel.GetSystemResourceLimit();
|
process->resource_limit = kernel.GetSystemResourceLimit();
|
||||||
process->status = ProcessStatus::Created;
|
process->status = ProcessStatus::Created;
|
||||||
|
@ -233,8 +234,8 @@ void Process::LoadModule(CodeSet module_, VAddr base_addr) {
|
||||||
Core::System::GetInstance().ArmInterface(3).ClearInstructionCache();
|
Core::System::GetInstance().ArmInterface(3).ClearInstructionCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
Kernel::Process::Process(KernelCore& kernel) : WaitObject{kernel} {}
|
Process::Process(Core::System& system) : WaitObject{system.Kernel()}, address_arbiter{system} {}
|
||||||
Kernel::Process::~Process() {}
|
Process::~Process() = default;
|
||||||
|
|
||||||
void Process::Acquire(Thread* thread) {
|
void Process::Acquire(Thread* thread) {
|
||||||
ASSERT_MSG(!ShouldWait(thread), "Object unavailable!");
|
ASSERT_MSG(!ShouldWait(thread), "Object unavailable!");
|
||||||
|
|
|
@ -12,12 +12,17 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <boost/container/static_vector.hpp>
|
#include <boost/container/static_vector.hpp>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "core/hle/kernel/address_arbiter.h"
|
||||||
#include "core/hle/kernel/handle_table.h"
|
#include "core/hle/kernel/handle_table.h"
|
||||||
#include "core/hle/kernel/process_capability.h"
|
#include "core/hle/kernel/process_capability.h"
|
||||||
#include "core/hle/kernel/vm_manager.h"
|
#include "core/hle/kernel/vm_manager.h"
|
||||||
#include "core/hle/kernel/wait_object.h"
|
#include "core/hle/kernel/wait_object.h"
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
class ProgramMetadata;
|
class ProgramMetadata;
|
||||||
}
|
}
|
||||||
|
@ -116,7 +121,7 @@ public:
|
||||||
|
|
||||||
static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4;
|
static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4;
|
||||||
|
|
||||||
static SharedPtr<Process> Create(KernelCore& kernel, std::string&& name);
|
static SharedPtr<Process> Create(Core::System& system, std::string&& name);
|
||||||
|
|
||||||
std::string GetTypeName() const override {
|
std::string GetTypeName() const override {
|
||||||
return "Process";
|
return "Process";
|
||||||
|
@ -150,6 +155,16 @@ public:
|
||||||
return handle_table;
|
return handle_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets a reference to the process' address arbiter.
|
||||||
|
AddressArbiter& GetAddressArbiter() {
|
||||||
|
return address_arbiter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets a const reference to the process' address arbiter.
|
||||||
|
const AddressArbiter& GetAddressArbiter() const {
|
||||||
|
return address_arbiter;
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets the current status of the process
|
/// Gets the current status of the process
|
||||||
ProcessStatus GetStatus() const {
|
ProcessStatus GetStatus() const {
|
||||||
return status;
|
return status;
|
||||||
|
@ -251,7 +266,7 @@ public:
|
||||||
void FreeTLSSlot(VAddr tls_address);
|
void FreeTLSSlot(VAddr tls_address);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit Process(KernelCore& kernel);
|
explicit Process(Core::System& kernel);
|
||||||
~Process() override;
|
~Process() override;
|
||||||
|
|
||||||
/// Checks if the specified thread should wait until this process is available.
|
/// Checks if the specified thread should wait until this process is available.
|
||||||
|
@ -309,6 +324,9 @@ private:
|
||||||
/// Per-process handle table for storing created object handles in.
|
/// Per-process handle table for storing created object handles in.
|
||||||
HandleTable handle_table;
|
HandleTable handle_table;
|
||||||
|
|
||||||
|
/// Per-process address arbiter.
|
||||||
|
AddressArbiter address_arbiter;
|
||||||
|
|
||||||
/// Random values for svcGetInfo RandomEntropy
|
/// Random values for svcGetInfo RandomEntropy
|
||||||
std::array<u64, RANDOM_ENTROPY_SIZE> random_entropy;
|
std::array<u64, RANDOM_ENTROPY_SIZE> random_entropy;
|
||||||
|
|
||||||
|
|
|
@ -1480,7 +1480,8 @@ static ResultCode WaitForAddress(VAddr address, u32 type, s32 value, s64 timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto arbitration_type = static_cast<AddressArbiter::ArbitrationType>(type);
|
const auto arbitration_type = static_cast<AddressArbiter::ArbitrationType>(type);
|
||||||
auto& address_arbiter = Core::System::GetInstance().Kernel().AddressArbiter();
|
auto& address_arbiter =
|
||||||
|
Core::System::GetInstance().Kernel().CurrentProcess()->GetAddressArbiter();
|
||||||
return address_arbiter.WaitForAddress(address, arbitration_type, value, timeout);
|
return address_arbiter.WaitForAddress(address, arbitration_type, value, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1500,7 +1501,8 @@ static ResultCode SignalToAddress(VAddr address, u32 type, s32 value, s32 num_to
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto signal_type = static_cast<AddressArbiter::SignalType>(type);
|
const auto signal_type = static_cast<AddressArbiter::SignalType>(type);
|
||||||
auto& address_arbiter = Core::System::GetInstance().Kernel().AddressArbiter();
|
auto& address_arbiter =
|
||||||
|
Core::System::GetInstance().Kernel().CurrentProcess()->GetAddressArbiter();
|
||||||
return address_arbiter.SignalToAddress(address, signal_type, value, num_to_wake);
|
return address_arbiter.SignalToAddress(address, signal_type, value, num_to_wake);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace ArmTests {
|
||||||
TestEnvironment::TestEnvironment(bool mutable_memory_)
|
TestEnvironment::TestEnvironment(bool mutable_memory_)
|
||||||
: mutable_memory(mutable_memory_),
|
: mutable_memory(mutable_memory_),
|
||||||
test_memory(std::make_shared<TestMemory>(this)), kernel{Core::System::GetInstance()} {
|
test_memory(std::make_shared<TestMemory>(this)), kernel{Core::System::GetInstance()} {
|
||||||
auto process = Kernel::Process::Create(kernel, "");
|
auto process = Kernel::Process::Create(Core::System::GetInstance(), "");
|
||||||
kernel.MakeCurrentProcess(process.get());
|
kernel.MakeCurrentProcess(process.get());
|
||||||
page_table = &process->VMManager().page_table;
|
page_table = &process->VMManager().page_table;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue