mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Kernel: Address Feedback.
This commit is contained in:
		
							parent
							
								
									ea956c823e
								
							
						
					
					
						commit
						d219a96cc8
					
				@ -3,6 +3,7 @@
 | 
				
			|||||||
// Refer to the license.txt file included.
 | 
					// Refer to the license.txt file included.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <atomic>
 | 
					#include <atomic>
 | 
				
			||||||
 | 
					#include <bitset>
 | 
				
			||||||
#include <functional>
 | 
					#include <functional>
 | 
				
			||||||
#include <memory>
 | 
					#include <memory>
 | 
				
			||||||
#include <mutex>
 | 
					#include <mutex>
 | 
				
			||||||
@ -17,6 +18,7 @@
 | 
				
			|||||||
#include "core/core.h"
 | 
					#include "core/core.h"
 | 
				
			||||||
#include "core/core_timing.h"
 | 
					#include "core/core_timing.h"
 | 
				
			||||||
#include "core/core_timing_util.h"
 | 
					#include "core/core_timing_util.h"
 | 
				
			||||||
 | 
					#include "core/hardware_properties.h"
 | 
				
			||||||
#include "core/hle/kernel/client_port.h"
 | 
					#include "core/hle/kernel/client_port.h"
 | 
				
			||||||
#include "core/hle/kernel/errors.h"
 | 
					#include "core/hle/kernel/errors.h"
 | 
				
			||||||
#include "core/hle/kernel/handle_table.h"
 | 
					#include "core/hle/kernel/handle_table.h"
 | 
				
			||||||
@ -188,6 +190,7 @@ struct KernelCore::Impl {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void RegisterCoreThread(std::size_t core_id) {
 | 
					    void RegisterCoreThread(std::size_t core_id) {
 | 
				
			||||||
 | 
					        std::unique_lock lock{register_thread_mutex};
 | 
				
			||||||
        const std::thread::id this_id = std::this_thread::get_id();
 | 
					        const std::thread::id this_id = std::this_thread::get_id();
 | 
				
			||||||
        const auto it = host_thread_ids.find(this_id);
 | 
					        const auto it = host_thread_ids.find(this_id);
 | 
				
			||||||
        ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
 | 
					        ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
 | 
				
			||||||
@ -198,13 +201,14 @@ struct KernelCore::Impl {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void RegisterHostThread() {
 | 
					    void RegisterHostThread() {
 | 
				
			||||||
 | 
					        std::unique_lock lock{register_thread_mutex};
 | 
				
			||||||
        const std::thread::id this_id = std::this_thread::get_id();
 | 
					        const std::thread::id this_id = std::this_thread::get_id();
 | 
				
			||||||
        const auto it = host_thread_ids.find(this_id);
 | 
					        const auto it = host_thread_ids.find(this_id);
 | 
				
			||||||
        ASSERT(it == host_thread_ids.end());
 | 
					        ASSERT(it == host_thread_ids.end());
 | 
				
			||||||
        host_thread_ids[this_id] = registered_thread_ids++;
 | 
					        host_thread_ids[this_id] = registered_thread_ids++;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    u32 GetCurrentHostThreadId() const {
 | 
					    u32 GetCurrentHostThreadID() const {
 | 
				
			||||||
        const std::thread::id this_id = std::this_thread::get_id();
 | 
					        const std::thread::id this_id = std::this_thread::get_id();
 | 
				
			||||||
        const auto it = host_thread_ids.find(this_id);
 | 
					        const auto it = host_thread_ids.find(this_id);
 | 
				
			||||||
        if (it == host_thread_ids.end()) {
 | 
					        if (it == host_thread_ids.end()) {
 | 
				
			||||||
@ -213,9 +217,9 @@ struct KernelCore::Impl {
 | 
				
			|||||||
        return it->second;
 | 
					        return it->second;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Core::EmuThreadHandle GetCurrentEmuThreadId() const {
 | 
					    Core::EmuThreadHandle GetCurrentEmuThreadID() const {
 | 
				
			||||||
        Core::EmuThreadHandle result = Core::EmuThreadHandle::InvalidHandle();
 | 
					        Core::EmuThreadHandle result = Core::EmuThreadHandle::InvalidHandle();
 | 
				
			||||||
        result.host_handle = GetCurrentHostThreadId();
 | 
					        result.host_handle = GetCurrentHostThreadID();
 | 
				
			||||||
        if (result.host_handle >= Core::Hardware::NUM_CPU_CORES) {
 | 
					        if (result.host_handle >= Core::Hardware::NUM_CPU_CORES) {
 | 
				
			||||||
            return result;
 | 
					            return result;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -246,8 +250,8 @@ struct KernelCore::Impl {
 | 
				
			|||||||
    std::shared_ptr<Core::Timing::EventType> thread_wakeup_event_type;
 | 
					    std::shared_ptr<Core::Timing::EventType> thread_wakeup_event_type;
 | 
				
			||||||
    std::shared_ptr<Core::Timing::EventType> preemption_event;
 | 
					    std::shared_ptr<Core::Timing::EventType> preemption_event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future,
 | 
					    // This is the kernel's handle table or supervisor handle table which
 | 
				
			||||||
    // allowing us to simply use a pool index or similar.
 | 
					    // stores all the objects in place.
 | 
				
			||||||
    Kernel::HandleTable global_handle_table;
 | 
					    Kernel::HandleTable global_handle_table;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// 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
 | 
				
			||||||
@ -257,10 +261,11 @@ struct KernelCore::Impl {
 | 
				
			|||||||
    std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor;
 | 
					    std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor;
 | 
				
			||||||
    std::vector<Kernel::PhysicalCore> cores;
 | 
					    std::vector<Kernel::PhysicalCore> cores;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 0-3 Ids represent core threads, >3 represent others
 | 
					    // 0-3 IDs represent core threads, >3 represent others
 | 
				
			||||||
    std::unordered_map<std::thread::id, u32> host_thread_ids;
 | 
					    std::unordered_map<std::thread::id, u32> host_thread_ids;
 | 
				
			||||||
    u32 registered_thread_ids{Core::Hardware::NUM_CPU_CORES};
 | 
					    u32 registered_thread_ids{Core::Hardware::NUM_CPU_CORES};
 | 
				
			||||||
    std::bitset<Core::Hardware::NUM_CPU_CORES> registered_core_threads{};
 | 
					    std::bitset<Core::Hardware::NUM_CPU_CORES> registered_core_threads;
 | 
				
			||||||
 | 
					    std::mutex register_thread_mutex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // System context
 | 
					    // System context
 | 
				
			||||||
    Core::System& system;
 | 
					    Core::System& system;
 | 
				
			||||||
@ -420,12 +425,12 @@ void KernelCore::RegisterHostThread() {
 | 
				
			|||||||
    impl->RegisterHostThread();
 | 
					    impl->RegisterHostThread();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
u32 KernelCore::GetCurrentHostThreadId() const {
 | 
					u32 KernelCore::GetCurrentHostThreadID() const {
 | 
				
			||||||
    return impl->GetCurrentHostThreadId();
 | 
					    return impl->GetCurrentHostThreadID();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Core::EmuThreadHandle KernelCore::GetCurrentEmuThreadId() const {
 | 
					Core::EmuThreadHandle KernelCore::GetCurrentEmuThreadID() const {
 | 
				
			||||||
    return impl->GetCurrentEmuThreadId();
 | 
					    return impl->GetCurrentEmuThreadID();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Kernel
 | 
					} // namespace Kernel
 | 
				
			||||||
 | 
				
			|||||||
@ -8,10 +8,10 @@
 | 
				
			|||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
#include <unordered_map>
 | 
					#include <unordered_map>
 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
#include "core/hardware_properties.h"
 | 
					 | 
				
			||||||
#include "core/hle/kernel/object.h"
 | 
					#include "core/hle/kernel/object.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Core {
 | 
					namespace Core {
 | 
				
			||||||
 | 
					struct EmuThreadHandle;
 | 
				
			||||||
class ExclusiveMonitor;
 | 
					class ExclusiveMonitor;
 | 
				
			||||||
class System;
 | 
					class System;
 | 
				
			||||||
} // namespace Core
 | 
					} // namespace Core
 | 
				
			||||||
@ -136,10 +136,10 @@ public:
 | 
				
			|||||||
    bool IsValidNamedPort(NamedPortTable::const_iterator port) const;
 | 
					    bool IsValidNamedPort(NamedPortTable::const_iterator port) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Gets the current host_thread/guest_thread handle.
 | 
					    /// Gets the current host_thread/guest_thread handle.
 | 
				
			||||||
    Core::EmuThreadHandle GetCurrentEmuThreadId() const;
 | 
					    Core::EmuThreadHandle GetCurrentEmuThreadID() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Gets the current host_thread handle.
 | 
					    /// Gets the current host_thread handle.
 | 
				
			||||||
    u32 GetCurrentHostThreadId() const;
 | 
					    u32 GetCurrentHostThreadID() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Register the current thread as a CPU Core Thread.
 | 
					    /// Register the current thread as a CPU Core Thread.
 | 
				
			||||||
    void RegisterCoreThread(std::size_t core_id);
 | 
					    void RegisterCoreThread(std::size_t core_id);
 | 
				
			||||||
 | 
				
			|||||||
@ -358,26 +358,29 @@ void GlobalScheduler::Shutdown() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void GlobalScheduler::Lock() {
 | 
					void GlobalScheduler::Lock() {
 | 
				
			||||||
    Core::EmuThreadHandle current_thread = kernel.GetCurrentEmuThreadId();
 | 
					    Core::EmuThreadHandle current_thread = kernel.GetCurrentEmuThreadID();
 | 
				
			||||||
    if (current_thread == current_owner) {
 | 
					    if (current_thread == current_owner) {
 | 
				
			||||||
        ++scope_lock;
 | 
					        ++scope_lock;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        inner_lock.lock();
 | 
					        inner_lock.lock();
 | 
				
			||||||
        current_owner = current_thread;
 | 
					        current_owner = current_thread;
 | 
				
			||||||
 | 
					        ASSERT(current_owner != Core::EmuThreadHandle::InvalidHandle());
 | 
				
			||||||
        scope_lock = 1;
 | 
					        scope_lock = 1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void GlobalScheduler::Unlock() {
 | 
					void GlobalScheduler::Unlock() {
 | 
				
			||||||
    if (--scope_lock == 0) {
 | 
					    if (--scope_lock != 0) {
 | 
				
			||||||
        for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
 | 
					        ASSERT(scope_lock > 0);
 | 
				
			||||||
            SelectThread(i);
 | 
					        return;
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        current_owner = Core::EmuThreadHandle::InvalidHandle();
 | 
					 | 
				
			||||||
        scope_lock = 1;
 | 
					 | 
				
			||||||
        inner_lock.unlock();
 | 
					 | 
				
			||||||
        // TODO(Blinkhawk): Setup the interrupts and change context on current core.
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
 | 
				
			||||||
 | 
					        SelectThread(i);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    current_owner = Core::EmuThreadHandle::InvalidHandle();
 | 
				
			||||||
 | 
					    scope_lock = 1;
 | 
				
			||||||
 | 
					    inner_lock.unlock();
 | 
				
			||||||
 | 
					    // TODO(Blinkhawk): Setup the interrupts and change context on current core.
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Scheduler::Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, std::size_t core_id)
 | 
					Scheduler::Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, std::size_t core_id)
 | 
				
			||||||
 | 
				
			|||||||
@ -171,7 +171,7 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /// Scheduler lock mechanisms.
 | 
					    /// Scheduler lock mechanisms.
 | 
				
			||||||
    std::mutex inner_lock{}; // TODO(Blinkhawk): Replace for a SpinLock
 | 
					    std::mutex inner_lock{}; // TODO(Blinkhawk): Replace for a SpinLock
 | 
				
			||||||
    std::atomic<std::size_t> scope_lock{};
 | 
					    std::atomic<s64> scope_lock{};
 | 
				
			||||||
    Core::EmuThreadHandle current_owner{Core::EmuThreadHandle::InvalidHandle()};
 | 
					    Core::EmuThreadHandle current_owner{Core::EmuThreadHandle::InvalidHandle()};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Lists all thread ids that aren't deleted/etc.
 | 
					    /// Lists all thread ids that aren't deleted/etc.
 | 
				
			||||||
@ -245,7 +245,7 @@ private:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class SchedulerLock {
 | 
					class SchedulerLock {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    SchedulerLock(KernelCore& kernel);
 | 
					    explicit SchedulerLock(KernelCore& kernel);
 | 
				
			||||||
    ~SchedulerLock();
 | 
					    ~SchedulerLock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
@ -254,8 +254,8 @@ protected:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class SchedulerLockAndSleep : public SchedulerLock {
 | 
					class SchedulerLockAndSleep : public SchedulerLock {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    SchedulerLockAndSleep(KernelCore& kernel, Handle& event_handle, Thread* time_task,
 | 
					    explicit SchedulerLockAndSleep(KernelCore& kernel, Handle& event_handle, Thread* time_task,
 | 
				
			||||||
                          s64 nanoseconds);
 | 
					                                   s64 nanoseconds);
 | 
				
			||||||
    ~SchedulerLockAndSleep();
 | 
					    ~SchedulerLockAndSleep();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void CancelSleep() {
 | 
					    void CancelSleep() {
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,7 @@
 | 
				
			|||||||
// Licensed under GPLv2 or any later version
 | 
					// Licensed under GPLv2 or any later version
 | 
				
			||||||
// Refer to the license.txt file included.
 | 
					// Refer to the license.txt file included.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "common/assert.h"
 | 
				
			||||||
#include "core/core.h"
 | 
					#include "core/core.h"
 | 
				
			||||||
#include "core/core_timing.h"
 | 
					#include "core/core_timing.h"
 | 
				
			||||||
#include "core/core_timing_util.h"
 | 
					#include "core/core_timing_util.h"
 | 
				
			||||||
@ -34,9 +35,10 @@ void TimeManager::ScheduleTimeEvent(Handle& event_handle, Thread* timetask, s64
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TimeManager::UnscheduleTimeEvent(Handle event_handle) {
 | 
					void TimeManager::UnscheduleTimeEvent(Handle event_handle) {
 | 
				
			||||||
    if (event_handle != InvalidHandle) {
 | 
					    if (event_handle == InvalidHandle) {
 | 
				
			||||||
        system.CoreTiming().UnscheduleEvent(time_manager_event_type, event_handle);
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    system.CoreTiming().UnscheduleEvent(time_manager_event_type, event_handle);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Kernel
 | 
					} // namespace Kernel
 | 
				
			||||||
 | 
				
			|||||||
@ -20,12 +20,19 @@ namespace Kernel {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class Thread;
 | 
					class Thread;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * The `TimeManager` takes care of scheduling time events on threads and executes their TimeUp
 | 
				
			||||||
 | 
					 * method when the event is triggered.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
class TimeManager {
 | 
					class TimeManager {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    TimeManager(Core::System& system);
 | 
					    explicit TimeManager(Core::System& system);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Schedule a time event on `timetask` thread that will expire in 'nanoseconds'
 | 
				
			||||||
 | 
					    /// returns a non-invalid handle in `event_handle` if correctly scheduled
 | 
				
			||||||
    void ScheduleTimeEvent(Handle& event_handle, Thread* timetask, s64 nanoseconds);
 | 
					    void ScheduleTimeEvent(Handle& event_handle, Thread* timetask, s64 nanoseconds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Unschedule an existing time event
 | 
				
			||||||
    void UnscheduleTimeEvent(Handle event_handle);
 | 
					    void UnscheduleTimeEvent(Handle event_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user