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);
 | 
			
		||||
}
 | 
			
		||||
struct System::Impl {
 | 
			
		||||
    explicit Impl(System& system) : kernel{system} {}
 | 
			
		||||
 | 
			
		||||
    Cpu& CurrentCpuCore() {
 | 
			
		||||
        return cpu_core_manager.GetCurrentCore();
 | 
			
		||||
@ -95,7 +96,7 @@ struct System::Impl {
 | 
			
		||||
        LOG_DEBUG(HW_Memory, "initialized OK");
 | 
			
		||||
 | 
			
		||||
        core_timing.Initialize();
 | 
			
		||||
        kernel.Initialize(core_timing);
 | 
			
		||||
        kernel.Initialize();
 | 
			
		||||
 | 
			
		||||
        const auto current_time = std::chrono::duration_cast<std::chrono::seconds>(
 | 
			
		||||
            std::chrono::system_clock::now().time_since_epoch());
 | 
			
		||||
@ -265,7 +266,7 @@ struct System::Impl {
 | 
			
		||||
    Core::FrameLimiter frame_limiter;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
System::System() : impl{std::make_unique<Impl>()} {}
 | 
			
		||||
System::System() : impl{std::make_unique<Impl>(*this)} {}
 | 
			
		||||
System::~System() = default;
 | 
			
		||||
 | 
			
		||||
Cpu& System::CurrentCpuCore() {
 | 
			
		||||
 | 
			
		||||
@ -39,7 +39,7 @@ void WakeThreads(const std::vector<SharedPtr<Thread>>& waiting_threads, s32 num_
 | 
			
		||||
}
 | 
			
		||||
} // Anonymous namespace
 | 
			
		||||
 | 
			
		||||
AddressArbiter::AddressArbiter() = default;
 | 
			
		||||
AddressArbiter::AddressArbiter(Core::System& system) : system{system} {}
 | 
			
		||||
AddressArbiter::~AddressArbiter() = default;
 | 
			
		||||
 | 
			
		||||
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) {
 | 
			
		||||
    SharedPtr<Thread> current_thread = GetCurrentThread();
 | 
			
		||||
    SharedPtr<Thread> current_thread = system.CurrentScheduler().GetCurrentThread();
 | 
			
		||||
    current_thread->SetArbiterWaitAddress(address);
 | 
			
		||||
    current_thread->SetStatus(ThreadStatus::WaitArb);
 | 
			
		||||
    current_thread->InvalidateWakeupCallback();
 | 
			
		||||
 | 
			
		||||
    current_thread->WakeAfterDelay(timeout);
 | 
			
		||||
 | 
			
		||||
    Core::System::GetInstance().CpuCore(current_thread->GetProcessorID()).PrepareReschedule();
 | 
			
		||||
    system.CpuCore(current_thread->GetProcessorID()).PrepareReschedule();
 | 
			
		||||
    return RESULT_TIMEOUT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
                                               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();
 | 
			
		||||
 | 
			
		||||
        for (const auto& thread : thread_list) {
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,10 @@
 | 
			
		||||
 | 
			
		||||
union ResultCode;
 | 
			
		||||
 | 
			
		||||
namespace Core {
 | 
			
		||||
class System;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Kernel {
 | 
			
		||||
 | 
			
		||||
class Thread;
 | 
			
		||||
@ -27,7 +31,7 @@ public:
 | 
			
		||||
        ModifyByWaitingCountAndSignalIfEqual = 2,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    AddressArbiter();
 | 
			
		||||
    explicit AddressArbiter(Core::System& system);
 | 
			
		||||
    ~AddressArbiter();
 | 
			
		||||
 | 
			
		||||
    AddressArbiter(const AddressArbiter&) = delete;
 | 
			
		||||
@ -61,6 +65,8 @@ private:
 | 
			
		||||
 | 
			
		||||
    // Gets the threads waiting on an address.
 | 
			
		||||
    std::vector<SharedPtr<Thread>> GetThreadsWaitingOnAddress(VAddr address) const;
 | 
			
		||||
 | 
			
		||||
    Core::System& system;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace Kernel
 | 
			
		||||
 | 
			
		||||
@ -87,11 +87,13 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] int cycles_
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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();
 | 
			
		||||
 | 
			
		||||
        InitializeSystemResourceLimit(kernel);
 | 
			
		||||
        InitializeThreads(core_timing);
 | 
			
		||||
        InitializeThreads();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void Shutdown() {
 | 
			
		||||
@ -123,9 +125,9 @@ struct KernelCore::Impl {
 | 
			
		||||
        ASSERT(system_resource_limit->SetLimitValue(ResourceType::Sessions, 900).IsSuccess());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void InitializeThreads(Core::Timing::CoreTiming& core_timing) {
 | 
			
		||||
    void InitializeThreads() {
 | 
			
		||||
        thread_wakeup_event_type =
 | 
			
		||||
            core_timing.RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback);
 | 
			
		||||
            system.CoreTiming().RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
    /// the ConnectToPort SVC.
 | 
			
		||||
    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() {
 | 
			
		||||
    Shutdown();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KernelCore::Initialize(Core::Timing::CoreTiming& core_timing) {
 | 
			
		||||
    impl->Initialize(*this, core_timing);
 | 
			
		||||
void KernelCore::Initialize() {
 | 
			
		||||
    impl->Initialize(*this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KernelCore::Shutdown() {
 | 
			
		||||
 | 
			
		||||
@ -11,6 +11,10 @@
 | 
			
		||||
template <typename T>
 | 
			
		||||
class ResultVal;
 | 
			
		||||
 | 
			
		||||
namespace Core {
 | 
			
		||||
class System;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Core::Timing {
 | 
			
		||||
class CoreTiming;
 | 
			
		||||
struct EventType;
 | 
			
		||||
@ -31,7 +35,14 @@ private:
 | 
			
		||||
    using NamedPortTable = std::unordered_map<std::string, SharedPtr<ClientPort>>;
 | 
			
		||||
 | 
			
		||||
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(const KernelCore&) = delete;
 | 
			
		||||
@ -41,11 +52,7 @@ public:
 | 
			
		||||
    KernelCore& operator=(KernelCore&&) = delete;
 | 
			
		||||
 | 
			
		||||
    /// Resets the kernel to a clean slate for use.
 | 
			
		||||
    ///
 | 
			
		||||
    /// @param core_timing CoreTiming instance used to create any necessary
 | 
			
		||||
    ///                    kernel-specific callback events.
 | 
			
		||||
    ///
 | 
			
		||||
    void Initialize(Core::Timing::CoreTiming& core_timing);
 | 
			
		||||
    void Initialize();
 | 
			
		||||
 | 
			
		||||
    /// Clears all resources in use by the kernel instance.
 | 
			
		||||
    void Shutdown();
 | 
			
		||||
 | 
			
		||||
@ -13,11 +13,11 @@
 | 
			
		||||
namespace ArmTests {
 | 
			
		||||
 | 
			
		||||
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, "");
 | 
			
		||||
    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);
 | 
			
		||||
    page_table->special_regions.clear();
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user