aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2019-01-18 20:26:39 -0200
committerGitHub <noreply@github.com>2019-01-18 20:26:39 -0200
commit22bacc618815170c0d186a82e1ea4558e36b7063 (patch)
tree79b97959481fea1ac301da6d4e9dea9b991ece6f /Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs
parent3731d0ce8412c3c48286c242842bcb4940b4ca6d (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.cs62
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;