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:
Lioncash 2019-03-07 18:48:14 -05:00
parent b7f331afa3
commit 8e510d5afa
8 changed files with 35 additions and 28 deletions

View file

@ -116,7 +116,7 @@ struct System::Impl {
if (web_browser == nullptr)
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());
telemetry_session = std::make_unique<Core::TelemetrySession>();

View file

@ -4,8 +4,10 @@
#pragma once
#include <vector>
#include "common/common_types.h"
#include "core/hle/kernel/address_arbiter.h"
#include "core/hle/kernel/object.h"
union ResultCode;

View file

@ -87,7 +87,7 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] int cycles_
}
struct KernelCore::Impl {
explicit Impl(Core::System& system) : address_arbiter{system}, system{system} {}
explicit Impl(Core::System& system) : system{system} {}
void Initialize(KernelCore& kernel) {
Shutdown();
@ -138,8 +138,6 @@ struct KernelCore::Impl {
std::vector<SharedPtr<Process>> process_list;
Process* current_process = nullptr;
Kernel::AddressArbiter address_arbiter;
SharedPtr<ResourceLimit> system_resource_limit;
Core::Timing::EventType* thread_wakeup_event_type = nullptr;
@ -192,14 +190,6 @@ const Process* KernelCore::CurrentProcess() const {
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) {
impl->named_ports.emplace(std::move(name), std::move(port));
}

View file

@ -75,12 +75,6 @@ public:
/// Retrieves a const pointer to the current process.
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
void AddNamedPort(std::string name, SharedPtr<ClientPort> port);

View file

@ -53,9 +53,10 @@ void SetupMainThread(Process& owner_process, KernelCore& kernel, VAddr entry_poi
CodeSet::CodeSet() = default;
CodeSet::~CodeSet() = default;
SharedPtr<Process> Process::Create(KernelCore& kernel, std::string&& name) {
SharedPtr<Process> process(new Process(kernel));
SharedPtr<Process> Process::Create(Core::System& system, std::string&& name) {
auto& kernel = system.Kernel();
SharedPtr<Process> process(new Process(system));
process->name = std::move(name);
process->resource_limit = kernel.GetSystemResourceLimit();
process->status = ProcessStatus::Created;
@ -233,8 +234,8 @@ void Process::LoadModule(CodeSet module_, VAddr base_addr) {
Core::System::GetInstance().ArmInterface(3).ClearInstructionCache();
}
Kernel::Process::Process(KernelCore& kernel) : WaitObject{kernel} {}
Kernel::Process::~Process() {}
Process::Process(Core::System& system) : WaitObject{system.Kernel()}, address_arbiter{system} {}
Process::~Process() = default;
void Process::Acquire(Thread* thread) {
ASSERT_MSG(!ShouldWait(thread), "Object unavailable!");

View file

@ -12,12 +12,17 @@
#include <vector>
#include <boost/container/static_vector.hpp>
#include "common/common_types.h"
#include "core/hle/kernel/address_arbiter.h"
#include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/process_capability.h"
#include "core/hle/kernel/vm_manager.h"
#include "core/hle/kernel/wait_object.h"
#include "core/hle/result.h"
namespace Core {
class System;
}
namespace FileSys {
class ProgramMetadata;
}
@ -116,7 +121,7 @@ public:
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 {
return "Process";
@ -150,6 +155,16 @@ public:
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
ProcessStatus GetStatus() const {
return status;
@ -251,7 +266,7 @@ public:
void FreeTLSSlot(VAddr tls_address);
private:
explicit Process(KernelCore& kernel);
explicit Process(Core::System& kernel);
~Process() override;
/// 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.
HandleTable handle_table;
/// Per-process address arbiter.
AddressArbiter address_arbiter;
/// Random values for svcGetInfo RandomEntropy
std::array<u64, RANDOM_ENTROPY_SIZE> random_entropy;

View file

@ -1480,7 +1480,8 @@ static ResultCode WaitForAddress(VAddr address, u32 type, s32 value, s64 timeout
}
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);
}
@ -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);
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);
}

View file

@ -15,7 +15,7 @@ namespace ArmTests {
TestEnvironment::TestEnvironment(bool mutable_memory_)
: mutable_memory(mutable_memory_),
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());
page_table = &process->VMManager().page_table;