forked from eden-emu/eden
		
	Merge pull request #11288 from liamwhite/svc-tick
kernel: remove relative task registration
This commit is contained in:
		
						commit
						fba72cc462
					
				
					 11 changed files with 67 additions and 33 deletions
				
			
		|  | @ -19,13 +19,7 @@ public: | |||
|     void Initialize(); | ||||
|     void Finalize(); | ||||
| 
 | ||||
|     s64 GetCount() const { | ||||
|         return GetTick(); | ||||
|     } | ||||
| 
 | ||||
|     void RegisterTask(KTimerTask* task, s64 time_from_now) { | ||||
|         this->RegisterAbsoluteTask(task, GetTick() + time_from_now); | ||||
|     } | ||||
|     s64 GetTick() const; | ||||
| 
 | ||||
|     void RegisterAbsoluteTask(KTimerTask* task, s64 task_time) { | ||||
|         KScopedDisableDispatch dd{m_kernel}; | ||||
|  | @ -42,7 +36,6 @@ private: | |||
|     void EnableInterrupt(s64 wakeup_time); | ||||
|     void DisableInterrupt(); | ||||
|     bool GetInterruptEnabled(); | ||||
|     s64 GetTick() const; | ||||
|     void DoTask(); | ||||
| 
 | ||||
| private: | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ | |||
| #include "common/overflow.h" | ||||
| #include "core/core.h" | ||||
| #include "core/core_timing.h" | ||||
| #include "core/hle/kernel/k_hardware_timer.h" | ||||
| #include "core/hle/kernel/k_resource_limit.h" | ||||
| #include "core/hle/kernel/svc_results.h" | ||||
| 
 | ||||
|  | @ -15,9 +16,7 @@ KResourceLimit::KResourceLimit(KernelCore& kernel) | |||
|     : KAutoObjectWithSlabHeapAndContainer{kernel}, m_lock{m_kernel}, m_cond_var{m_kernel} {} | ||||
| KResourceLimit::~KResourceLimit() = default; | ||||
| 
 | ||||
| void KResourceLimit::Initialize(const Core::Timing::CoreTiming* core_timing) { | ||||
|     m_core_timing = core_timing; | ||||
| } | ||||
| void KResourceLimit::Initialize() {} | ||||
| 
 | ||||
| void KResourceLimit::Finalize() {} | ||||
| 
 | ||||
|  | @ -86,7 +85,7 @@ Result KResourceLimit::SetLimitValue(LimitableResource which, s64 value) { | |||
| } | ||||
| 
 | ||||
| bool KResourceLimit::Reserve(LimitableResource which, s64 value) { | ||||
|     return Reserve(which, value, m_core_timing->GetGlobalTimeNs().count() + DefaultTimeout); | ||||
|     return Reserve(which, value, m_kernel.HardwareTimer().GetTick() + DefaultTimeout); | ||||
| } | ||||
| 
 | ||||
| bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) { | ||||
|  | @ -117,7 +116,7 @@ bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) { | |||
|         } | ||||
| 
 | ||||
|         if (m_current_hints[index] + value <= m_limit_values[index] && | ||||
|             (timeout < 0 || m_core_timing->GetGlobalTimeNs().count() < timeout)) { | ||||
|             (timeout < 0 || m_kernel.HardwareTimer().GetTick() < timeout)) { | ||||
|             m_waiter_count++; | ||||
|             m_cond_var.Wait(std::addressof(m_lock), timeout, false); | ||||
|             m_waiter_count--; | ||||
|  | @ -154,7 +153,7 @@ void KResourceLimit::Release(LimitableResource which, s64 value, s64 hint) { | |||
| 
 | ||||
| KResourceLimit* CreateResourceLimitForProcess(Core::System& system, s64 physical_memory_size) { | ||||
|     auto* resource_limit = KResourceLimit::Create(system.Kernel()); | ||||
|     resource_limit->Initialize(std::addressof(system.CoreTiming())); | ||||
|     resource_limit->Initialize(); | ||||
| 
 | ||||
|     // Initialize default resource limit values.
 | ||||
|     // TODO(bunnei): These values are the system defaults, the limits for service processes are
 | ||||
|  |  | |||
|  | @ -31,7 +31,7 @@ public: | |||
|     explicit KResourceLimit(KernelCore& kernel); | ||||
|     ~KResourceLimit() override; | ||||
| 
 | ||||
|     void Initialize(const Core::Timing::CoreTiming* core_timing); | ||||
|     void Initialize(); | ||||
|     void Finalize() override; | ||||
| 
 | ||||
|     s64 GetLimitValue(LimitableResource which) const; | ||||
|  | @ -57,7 +57,6 @@ private: | |||
|     mutable KLightLock m_lock; | ||||
|     s32 m_waiter_count{}; | ||||
|     KLightConditionVariable m_cond_var; | ||||
|     const Core::Timing::CoreTiming* m_core_timing{}; | ||||
| }; | ||||
| 
 | ||||
| KResourceLimit* CreateResourceLimitForProcess(Core::System& system, s64 physical_memory_size); | ||||
|  |  | |||
|  | @ -28,7 +28,7 @@ public: | |||
|     ~KScopedSchedulerLockAndSleep() { | ||||
|         // Register the sleep.
 | ||||
|         if (m_timeout_tick > 0) { | ||||
|             m_timer->RegisterTask(m_thread, m_timeout_tick); | ||||
|             m_timer->RegisterAbsoluteTask(m_thread, m_timeout_tick); | ||||
|         } | ||||
| 
 | ||||
|         // Unlock the scheduler.
 | ||||
|  |  | |||
|  | @ -231,7 +231,7 @@ struct KernelCore::Impl { | |||
|     void InitializeSystemResourceLimit(KernelCore& kernel, | ||||
|                                        const Core::Timing::CoreTiming& core_timing) { | ||||
|         system_resource_limit = KResourceLimit::Create(system.Kernel()); | ||||
|         system_resource_limit->Initialize(&core_timing); | ||||
|         system_resource_limit->Initialize(); | ||||
|         KResourceLimit::Register(kernel, system_resource_limit); | ||||
| 
 | ||||
|         const auto sizes{memory_layout->GetTotalAndKernelMemorySizes()}; | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ | |||
| // SPDX-License-Identifier: GPL-2.0-or-later
 | ||||
| 
 | ||||
| #include "core/core.h" | ||||
| #include "core/hle/kernel/k_hardware_timer.h" | ||||
| #include "core/hle/kernel/k_memory_layout.h" | ||||
| #include "core/hle/kernel/k_process.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
|  | @ -52,7 +53,7 @@ Result WaitForAddress(Core::System& system, u64 address, ArbitrationType arb_typ | |||
|     if (timeout_ns > 0) { | ||||
|         const s64 offset_tick(timeout_ns); | ||||
|         if (offset_tick > 0) { | ||||
|             timeout = offset_tick + 2; | ||||
|             timeout = system.Kernel().HardwareTimer().GetTick() + offset_tick + 2; | ||||
|             if (timeout <= 0) { | ||||
|                 timeout = std::numeric_limits<s64>::max(); | ||||
|             } | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ | |||
| // SPDX-License-Identifier: GPL-2.0-or-later
 | ||||
| 
 | ||||
| #include "core/core.h" | ||||
| #include "core/hle/kernel/k_hardware_timer.h" | ||||
| #include "core/hle/kernel/k_memory_layout.h" | ||||
| #include "core/hle/kernel/k_process.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
|  | @ -25,7 +26,7 @@ Result WaitProcessWideKeyAtomic(Core::System& system, u64 address, u64 cv_key, u | |||
|     if (timeout_ns > 0) { | ||||
|         const s64 offset_tick(timeout_ns); | ||||
|         if (offset_tick > 0) { | ||||
|             timeout = offset_tick + 2; | ||||
|             timeout = system.Kernel().HardwareTimer().GetTick() + offset_tick + 2; | ||||
|             if (timeout <= 0) { | ||||
|                 timeout = std::numeric_limits<s64>::max(); | ||||
|             } | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ | |||
| #include "common/scratch_buffer.h" | ||||
| #include "core/core.h" | ||||
| #include "core/hle/kernel/k_client_session.h" | ||||
| #include "core/hle/kernel/k_hardware_timer.h" | ||||
| #include "core/hle/kernel/k_process.h" | ||||
| #include "core/hle/kernel/k_server_session.h" | ||||
| #include "core/hle/kernel/svc.h" | ||||
|  | @ -82,12 +83,29 @@ Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_ad | |||
|         R_TRY(session->SendReply()); | ||||
|     } | ||||
| 
 | ||||
|     // Convert the timeout from nanoseconds to ticks.
 | ||||
|     // NOTE: Nintendo does not use this conversion logic in WaitSynchronization...
 | ||||
|     s64 timeout; | ||||
|     if (timeout_ns > 0) { | ||||
|         const s64 offset_tick(timeout_ns); | ||||
|         if (offset_tick > 0) { | ||||
|             timeout = kernel.HardwareTimer().GetTick() + offset_tick + 2; | ||||
|             if (timeout <= 0) { | ||||
|                 timeout = std::numeric_limits<s64>::max(); | ||||
|             } | ||||
|         } else { | ||||
|             timeout = std::numeric_limits<s64>::max(); | ||||
|         } | ||||
|     } else { | ||||
|         timeout = timeout_ns; | ||||
|     } | ||||
| 
 | ||||
|     // Wait for a message.
 | ||||
|     while (true) { | ||||
|         // Wait for an object.
 | ||||
|         s32 index; | ||||
|         Result result = KSynchronizationObject::Wait(kernel, std::addressof(index), objs.data(), | ||||
|                                                      num_handles, timeout_ns); | ||||
|                                                      num_handles, timeout); | ||||
|         if (result == ResultTimedOut) { | ||||
|             R_RETURN(result); | ||||
|         } | ||||
|  |  | |||
|  | @ -21,7 +21,7 @@ Result CreateResourceLimit(Core::System& system, Handle* out_handle) { | |||
|     SCOPE_EXIT({ resource_limit->Close(); }); | ||||
| 
 | ||||
|     // Initialize the resource limit.
 | ||||
|     resource_limit->Initialize(std::addressof(system.CoreTiming())); | ||||
|     resource_limit->Initialize(); | ||||
| 
 | ||||
|     // Register the limit.
 | ||||
|     KResourceLimit::Register(kernel, resource_limit); | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
| #include "common/scope_exit.h" | ||||
| #include "common/scratch_buffer.h" | ||||
| #include "core/core.h" | ||||
| #include "core/hle/kernel/k_hardware_timer.h" | ||||
| #include "core/hle/kernel/k_process.h" | ||||
| #include "core/hle/kernel/k_readable_event.h" | ||||
| #include "core/hle/kernel/svc.h" | ||||
|  | @ -83,9 +84,20 @@ Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_ha | |||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     // Convert the timeout from nanoseconds to ticks.
 | ||||
|     s64 timeout; | ||||
|     if (timeout_ns > 0) { | ||||
|         u64 ticks = kernel.HardwareTimer().GetTick(); | ||||
|         ticks += timeout_ns; | ||||
|         ticks += 2; | ||||
| 
 | ||||
|         timeout = ticks; | ||||
|     } else { | ||||
|         timeout = timeout_ns; | ||||
|     } | ||||
| 
 | ||||
|     // Wait on the objects.
 | ||||
|     Result res = | ||||
|         KSynchronizationObject::Wait(kernel, out_index, objs.data(), num_handles, timeout_ns); | ||||
|     Result res = KSynchronizationObject::Wait(kernel, out_index, objs.data(), num_handles, timeout); | ||||
| 
 | ||||
|     R_SUCCEED_IF(res == ResultSessionClosed); | ||||
|     R_RETURN(res); | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
| #include "common/scope_exit.h" | ||||
| #include "core/core.h" | ||||
| #include "core/core_timing.h" | ||||
| #include "core/hle/kernel/k_hardware_timer.h" | ||||
| #include "core/hle/kernel/k_process.h" | ||||
| #include "core/hle/kernel/k_scoped_resource_reservation.h" | ||||
| #include "core/hle/kernel/k_thread.h" | ||||
|  | @ -42,9 +43,9 @@ Result CreateThread(Core::System& system, Handle* out_handle, u64 entry_point, u | |||
|     R_UNLESS(process.CheckThreadPriority(priority), ResultInvalidPriority); | ||||
| 
 | ||||
|     // Reserve a new thread from the process resource limit (waiting up to 100ms).
 | ||||
|     KScopedResourceReservation thread_reservation( | ||||
|         std::addressof(process), LimitableResource::ThreadCountMax, 1, | ||||
|         system.CoreTiming().GetGlobalTimeNs().count() + 100000000); | ||||
|     KScopedResourceReservation thread_reservation(std::addressof(process), | ||||
|                                                   LimitableResource::ThreadCountMax, 1, | ||||
|                                                   kernel.HardwareTimer().GetTick() + 100000000); | ||||
|     R_UNLESS(thread_reservation.Succeeded(), ResultLimitReached); | ||||
| 
 | ||||
|     // Create the thread.
 | ||||
|  | @ -102,20 +103,31 @@ void ExitThread(Core::System& system) { | |||
| } | ||||
| 
 | ||||
| /// Sleep the current thread
 | ||||
| void SleepThread(Core::System& system, s64 nanoseconds) { | ||||
| void SleepThread(Core::System& system, s64 ns) { | ||||
|     auto& kernel = system.Kernel(); | ||||
|     const auto yield_type = static_cast<Svc::YieldType>(nanoseconds); | ||||
|     const auto yield_type = static_cast<Svc::YieldType>(ns); | ||||
| 
 | ||||
|     LOG_TRACE(Kernel_SVC, "called nanoseconds={}", nanoseconds); | ||||
|     LOG_TRACE(Kernel_SVC, "called nanoseconds={}", ns); | ||||
| 
 | ||||
|     // When the input tick is positive, sleep.
 | ||||
|     if (nanoseconds > 0) { | ||||
|     if (ns > 0) { | ||||
|         // Convert the timeout from nanoseconds to ticks.
 | ||||
|         // NOTE: Nintendo does not use this conversion logic in WaitSynchronization...
 | ||||
|         s64 timeout; | ||||
| 
 | ||||
|         const s64 offset_tick(ns); | ||||
|         if (offset_tick > 0) { | ||||
|             timeout = kernel.HardwareTimer().GetTick() + offset_tick + 2; | ||||
|             if (timeout <= 0) { | ||||
|                 timeout = std::numeric_limits<s64>::max(); | ||||
|             } | ||||
|         } else { | ||||
|             timeout = std::numeric_limits<s64>::max(); | ||||
|         } | ||||
| 
 | ||||
|         // Sleep.
 | ||||
|         // NOTE: Nintendo does not check the result of this sleep.
 | ||||
|         static_cast<void>(GetCurrentThread(kernel).Sleep(nanoseconds)); | ||||
|         static_cast<void>(GetCurrentThread(kernel).Sleep(timeout)); | ||||
|     } else if (yield_type == Svc::YieldType::WithoutCoreMigration) { | ||||
|         KScheduler::YieldWithoutCoreMigration(kernel); | ||||
|     } else if (yield_type == Svc::YieldType::WithCoreMigration) { | ||||
|  | @ -124,7 +136,6 @@ void SleepThread(Core::System& system, s64 nanoseconds) { | |||
|         KScheduler::YieldToAnyThread(kernel); | ||||
|     } else { | ||||
|         // Nintendo does nothing at all if an otherwise invalid value is passed.
 | ||||
|         ASSERT_MSG(false, "Unimplemented sleep yield type '{:016X}'!", nanoseconds); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 liamwhite
						liamwhite