diff options
author | gdkchan <gab.dark.100@gmail.com> | 2019-01-18 20:26:39 -0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-01-18 20:26:39 -0200 |
commit | 22bacc618815170c0d186a82e1ea4558e36b7063 (patch) | |
tree | 79b97959481fea1ac301da6d4e9dea9b991ece6f /Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs | |
parent | 3731d0ce8412c3c48286c242842bcb4940b4ca6d (diff) |
Improve kernel IPC implementation (#550)
* Implement some IPC related kernel SVCs properly
* Fix BLZ decompression when the segment also has a uncompressed chunck
* Set default cpu core on process start from ProgramLoader, remove debug message
* Load process capabilities properly on KIPs
* Fix a copy/paste error in UnmapPhysicalMemory64
* Implement smarter switching between old and new IPC system to support the old HLE services implementation without the manual switch
* Implement RegisterService on sm and AcceptSession (partial)
* Misc fixes and improvements on new IPC methods
* Move IPC related SVCs into a separate file, and logging on RegisterService (sm)
* Some small fixes related to receive list buffers and error cases
* Load NSOs using the correct pool partition
* Fix corner case on GetMaskFromMinMax where range is 64, doesn't happen in pratice however
* Fix send static buffer copy
* Session release, implement closing requests on client disconnect
* Implement ConnectToPort SVC
* KLightSession init
Diffstat (limited to 'Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs')
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs | 62 |
1 files changed, 50 insertions, 12 deletions
diff --git a/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs b/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs index 3ad64024..302e8f41 100644 --- a/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs +++ b/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs @@ -30,6 +30,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading private ulong _tlsAddress; + public ulong TlsAddress => _tlsAddress; + public ulong TlsDramAddress { get; private set; } + public long LastScheduledTime { get; set; } public LinkedListNode<KThread>[] SiblingsPerCore { get; private set; } @@ -67,6 +70,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading public bool WaitingSync { get; set; } private bool _hasExited; + private bool _hasBeenInitialized; + private bool _hasBeenReleased; public bool WaitingInArbitration { get; set; } @@ -124,6 +129,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading return KernelResult.OutOfMemory; } + TlsDramAddress = owner.MemoryManager.GetDramAddressFromVa(_tlsAddress); + MemoryHelper.FillWithZeros(owner.CpuMemory, (long)_tlsAddress, KTlsPageInfo.TlsEntrySize); } @@ -133,6 +140,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading { Owner = owner; + owner.IncrementReferenceCount(); owner.IncrementThreadCount(); is64Bits = (owner.MmuFlags & 1) != 0; @@ -156,6 +164,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading ThreadUid = System.GetThreadUid(); + _hasBeenInitialized = true; + if (owner != null) { owner.AddThread(this); @@ -252,6 +262,15 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading public void Exit() { + //TODO: Debug event. + + if (Owner != null) + { + Owner.ResourceLimit?.Release(LimitableResource.Thread, 0, 1); + + _hasBeenReleased = true; + } + System.CriticalSection.Enter(); _forcePauseFlags &= ~ThreadSchedState.ForcePauseMask; @@ -259,6 +278,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading ExitImpl(); System.CriticalSection.Leave(); + + DecrementReferenceCount(); } private void ExitImpl() @@ -930,7 +951,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading return; } - //Remove from old queues. + //Remove thread from the old priority queues. for (int core = 0; core < KScheduler.CpuCoresCount; core++) { if (((oldAffinityMask >> core) & 1) != 0) @@ -946,7 +967,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading } } - //Insert on new queues. + //Add thread to the new priority queues. for (int core = 0; core < KScheduler.CpuCoresCount; core++) { if (((AffinityMask >> core) & 1) != 0) @@ -965,11 +986,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading _scheduler.ThreadReselectionRequested = true; } - public override bool IsSignaled() - { - return _hasExited; - } - public void SetEntryArguments(long argsPtr, int threadHandle) { Context.ThreadState.X0 = (ulong)argsPtr; @@ -994,13 +1010,36 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading private void ThreadFinishedHandler(object sender, EventArgs e) { System.Scheduler.ExitThread(this); + System.Scheduler.RemoveThread(this); + } - Terminate(); + public override bool IsSignaled() + { + return _hasExited; + } - System.Scheduler.RemoveThread(this); + protected override void Destroy() + { + if (_hasBeenInitialized) + { + FreeResources(); + + bool released = Owner != null || _hasBeenReleased; + + if (Owner != null) + { + Owner.ResourceLimit?.Release(LimitableResource.Thread, 1, released ? 0 : 1); + + Owner.DecrementReferenceCount(); + } + else + { + System.ResourceLimit.Release(LimitableResource.Thread, 1, released ? 0 : 1); + } + } } - public void Terminate() + private void FreeResources() { Owner?.RemoveThread(this); @@ -1011,8 +1050,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading System.CriticalSection.Enter(); - //Wake up all threads that may be waiting for a mutex being held - //by this thread. + //Wake up all threads that may be waiting for a mutex being held by this thread. foreach (KThread thread in _mutexWaiters) { thread.MutexOwner = null; |