mirror of
https://gitlab.com/suyu-emu/suyu.git
synced 2024-03-15 23:15:44 +00:00
kernel/address_arbiter: Pass in system instance to constructor
Allows getting rid of reliance on the global accessor functions and instead operating on the provided system instance.
This commit is contained in:
parent
9d9676f620
commit
c161389a0f
|
@ -78,6 +78,7 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
|
||||||
return vfs->OpenFile(path, FileSys::Mode::Read);
|
return vfs->OpenFile(path, FileSys::Mode::Read);
|
||||||
}
|
}
|
||||||
struct System::Impl {
|
struct System::Impl {
|
||||||
|
explicit Impl(System& system) : kernel{system} {}
|
||||||
|
|
||||||
Cpu& CurrentCpuCore() {
|
Cpu& CurrentCpuCore() {
|
||||||
return cpu_core_manager.GetCurrentCore();
|
return cpu_core_manager.GetCurrentCore();
|
||||||
|
@ -95,7 +96,7 @@ struct System::Impl {
|
||||||
LOG_DEBUG(HW_Memory, "initialized OK");
|
LOG_DEBUG(HW_Memory, "initialized OK");
|
||||||
|
|
||||||
core_timing.Initialize();
|
core_timing.Initialize();
|
||||||
kernel.Initialize(core_timing);
|
kernel.Initialize();
|
||||||
|
|
||||||
const auto current_time = std::chrono::duration_cast<std::chrono::seconds>(
|
const auto current_time = std::chrono::duration_cast<std::chrono::seconds>(
|
||||||
std::chrono::system_clock::now().time_since_epoch());
|
std::chrono::system_clock::now().time_since_epoch());
|
||||||
|
@ -265,7 +266,7 @@ struct System::Impl {
|
||||||
Core::FrameLimiter frame_limiter;
|
Core::FrameLimiter frame_limiter;
|
||||||
};
|
};
|
||||||
|
|
||||||
System::System() : impl{std::make_unique<Impl>()} {}
|
System::System() : impl{std::make_unique<Impl>(*this)} {}
|
||||||
System::~System() = default;
|
System::~System() = default;
|
||||||
|
|
||||||
Cpu& System::CurrentCpuCore() {
|
Cpu& System::CurrentCpuCore() {
|
||||||
|
|
|
@ -39,7 +39,7 @@ void WakeThreads(const std::vector<SharedPtr<Thread>>& waiting_threads, s32 num_
|
||||||
}
|
}
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
AddressArbiter::AddressArbiter() = default;
|
AddressArbiter::AddressArbiter(Core::System& system) : system{system} {}
|
||||||
AddressArbiter::~AddressArbiter() = default;
|
AddressArbiter::~AddressArbiter() = default;
|
||||||
|
|
||||||
ResultCode AddressArbiter::SignalToAddress(VAddr address, s32 num_to_wake) {
|
ResultCode AddressArbiter::SignalToAddress(VAddr address, s32 num_to_wake) {
|
||||||
|
@ -134,22 +134,22 @@ ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 t
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode AddressArbiter::WaitForAddress(VAddr address, s64 timeout) {
|
ResultCode AddressArbiter::WaitForAddress(VAddr address, s64 timeout) {
|
||||||
SharedPtr<Thread> current_thread = GetCurrentThread();
|
SharedPtr<Thread> current_thread = system.CurrentScheduler().GetCurrentThread();
|
||||||
current_thread->SetArbiterWaitAddress(address);
|
current_thread->SetArbiterWaitAddress(address);
|
||||||
current_thread->SetStatus(ThreadStatus::WaitArb);
|
current_thread->SetStatus(ThreadStatus::WaitArb);
|
||||||
current_thread->InvalidateWakeupCallback();
|
current_thread->InvalidateWakeupCallback();
|
||||||
|
|
||||||
current_thread->WakeAfterDelay(timeout);
|
current_thread->WakeAfterDelay(timeout);
|
||||||
|
|
||||||
Core::System::GetInstance().CpuCore(current_thread->GetProcessorID()).PrepareReschedule();
|
system.CpuCore(current_thread->GetProcessorID()).PrepareReschedule();
|
||||||
return RESULT_TIMEOUT;
|
return RESULT_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<SharedPtr<Thread>> AddressArbiter::GetThreadsWaitingOnAddress(VAddr address) const {
|
std::vector<SharedPtr<Thread>> AddressArbiter::GetThreadsWaitingOnAddress(VAddr address) const {
|
||||||
const auto RetrieveWaitingThreads = [](std::size_t core_index,
|
const auto RetrieveWaitingThreads = [this](std::size_t core_index,
|
||||||
std::vector<SharedPtr<Thread>>& waiting_threads,
|
std::vector<SharedPtr<Thread>>& waiting_threads,
|
||||||
VAddr arb_addr) {
|
VAddr arb_addr) {
|
||||||
const auto& scheduler = Core::System::GetInstance().Scheduler(core_index);
|
const auto& scheduler = system.Scheduler(core_index);
|
||||||
const auto& thread_list = scheduler.GetThreadList();
|
const auto& thread_list = scheduler.GetThreadList();
|
||||||
|
|
||||||
for (const auto& thread : thread_list) {
|
for (const auto& thread : thread_list) {
|
||||||
|
|
|
@ -9,6 +9,10 @@
|
||||||
|
|
||||||
union ResultCode;
|
union ResultCode;
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
class Thread;
|
class Thread;
|
||||||
|
@ -27,7 +31,7 @@ public:
|
||||||
ModifyByWaitingCountAndSignalIfEqual = 2,
|
ModifyByWaitingCountAndSignalIfEqual = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
AddressArbiter();
|
explicit AddressArbiter(Core::System& system);
|
||||||
~AddressArbiter();
|
~AddressArbiter();
|
||||||
|
|
||||||
AddressArbiter(const AddressArbiter&) = delete;
|
AddressArbiter(const AddressArbiter&) = delete;
|
||||||
|
@ -61,6 +65,8 @@ private:
|
||||||
|
|
||||||
// Gets the threads waiting on an address.
|
// Gets the threads waiting on an address.
|
||||||
std::vector<SharedPtr<Thread>> GetThreadsWaitingOnAddress(VAddr address) const;
|
std::vector<SharedPtr<Thread>> GetThreadsWaitingOnAddress(VAddr address) const;
|
||||||
|
|
||||||
|
Core::System& system;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -87,11 +87,13 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] int cycles_
|
||||||
}
|
}
|
||||||
|
|
||||||
struct KernelCore::Impl {
|
struct KernelCore::Impl {
|
||||||
void Initialize(KernelCore& kernel, Core::Timing::CoreTiming& core_timing) {
|
explicit Impl(Core::System& system) : address_arbiter{system}, system{system} {}
|
||||||
|
|
||||||
|
void Initialize(KernelCore& kernel) {
|
||||||
Shutdown();
|
Shutdown();
|
||||||
|
|
||||||
InitializeSystemResourceLimit(kernel);
|
InitializeSystemResourceLimit(kernel);
|
||||||
InitializeThreads(core_timing);
|
InitializeThreads();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shutdown() {
|
void Shutdown() {
|
||||||
|
@ -123,9 +125,9 @@ struct KernelCore::Impl {
|
||||||
ASSERT(system_resource_limit->SetLimitValue(ResourceType::Sessions, 900).IsSuccess());
|
ASSERT(system_resource_limit->SetLimitValue(ResourceType::Sessions, 900).IsSuccess());
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeThreads(Core::Timing::CoreTiming& core_timing) {
|
void InitializeThreads() {
|
||||||
thread_wakeup_event_type =
|
thread_wakeup_event_type =
|
||||||
core_timing.RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback);
|
system.CoreTiming().RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::atomic<u32> next_object_id{0};
|
std::atomic<u32> next_object_id{0};
|
||||||
|
@ -148,15 +150,18 @@ struct KernelCore::Impl {
|
||||||
/// Map of named ports managed by the kernel, which can be retrieved using
|
/// Map of named ports managed by the kernel, which can be retrieved using
|
||||||
/// the ConnectToPort SVC.
|
/// the ConnectToPort SVC.
|
||||||
NamedPortTable named_ports;
|
NamedPortTable named_ports;
|
||||||
|
|
||||||
|
// System context
|
||||||
|
Core::System& system;
|
||||||
};
|
};
|
||||||
|
|
||||||
KernelCore::KernelCore() : impl{std::make_unique<Impl>()} {}
|
KernelCore::KernelCore(Core::System& system) : impl{std::make_unique<Impl>(system)} {}
|
||||||
KernelCore::~KernelCore() {
|
KernelCore::~KernelCore() {
|
||||||
Shutdown();
|
Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelCore::Initialize(Core::Timing::CoreTiming& core_timing) {
|
void KernelCore::Initialize() {
|
||||||
impl->Initialize(*this, core_timing);
|
impl->Initialize(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelCore::Shutdown() {
|
void KernelCore::Shutdown() {
|
||||||
|
|
|
@ -11,6 +11,10 @@
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ResultVal;
|
class ResultVal;
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Core::Timing {
|
namespace Core::Timing {
|
||||||
class CoreTiming;
|
class CoreTiming;
|
||||||
struct EventType;
|
struct EventType;
|
||||||
|
@ -31,7 +35,14 @@ private:
|
||||||
using NamedPortTable = std::unordered_map<std::string, SharedPtr<ClientPort>>;
|
using NamedPortTable = std::unordered_map<std::string, SharedPtr<ClientPort>>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
KernelCore();
|
/// Constructs an instance of the kernel using the given System
|
||||||
|
/// instance as a context for any necessary system-related state,
|
||||||
|
/// such as threads, CPU core state, etc.
|
||||||
|
///
|
||||||
|
/// @post After execution of the constructor, the provided System
|
||||||
|
/// object *must* outlive the kernel instance itself.
|
||||||
|
///
|
||||||
|
explicit KernelCore(Core::System& system);
|
||||||
~KernelCore();
|
~KernelCore();
|
||||||
|
|
||||||
KernelCore(const KernelCore&) = delete;
|
KernelCore(const KernelCore&) = delete;
|
||||||
|
@ -41,11 +52,7 @@ public:
|
||||||
KernelCore& operator=(KernelCore&&) = delete;
|
KernelCore& operator=(KernelCore&&) = delete;
|
||||||
|
|
||||||
/// Resets the kernel to a clean slate for use.
|
/// Resets the kernel to a clean slate for use.
|
||||||
///
|
void Initialize();
|
||||||
/// @param core_timing CoreTiming instance used to create any necessary
|
|
||||||
/// kernel-specific callback events.
|
|
||||||
///
|
|
||||||
void Initialize(Core::Timing::CoreTiming& core_timing);
|
|
||||||
|
|
||||||
/// Clears all resources in use by the kernel instance.
|
/// Clears all resources in use by the kernel instance.
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
|
@ -13,11 +13,11 @@
|
||||||
namespace ArmTests {
|
namespace ArmTests {
|
||||||
|
|
||||||
TestEnvironment::TestEnvironment(bool mutable_memory_)
|
TestEnvironment::TestEnvironment(bool mutable_memory_)
|
||||||
: mutable_memory(mutable_memory_), test_memory(std::make_shared<TestMemory>(this)) {
|
: 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(kernel, "");
|
||||||
kernel.MakeCurrentProcess(process.get());
|
kernel.MakeCurrentProcess(process.get());
|
||||||
page_table = &Core::CurrentProcess()->VMManager().page_table;
|
page_table = &process->VMManager().page_table;
|
||||||
|
|
||||||
std::fill(page_table->pointers.begin(), page_table->pointers.end(), nullptr);
|
std::fill(page_table->pointers.begin(), page_table->pointers.end(), nullptr);
|
||||||
page_table->special_regions.clear();
|
page_table->special_regions.clear();
|
||||||
|
|
Loading…
Reference in a new issue