ryujinx/Ryujinx.HLE/HOS/Kernel/KernelContext.cs
gdkchan cf6cd71488
IPC refactor part 2: Use ReplyAndReceive on HLE services and remove special handling from kernel (#1458)
* IPC refactor part 2: Use ReplyAndReceive on HLE services and remove special handling from kernel

* Fix for applet transfer memory + some nits

* Keep handles if possible to avoid server handle table exhaustion

* Fix IPC ZeroFill bug

* am: Correctly implement CreateManagedDisplayLayer and implement CreateManagedDisplaySeparableLayer

CreateManagedDisplaySeparableLayer is requires since 10.x+ when appletResourceUserId != 0

* Make it exit properly

* Make ServiceNotImplementedException show the full message again

* Allow yielding execution to avoid starving other threads

* Only wait if active

* Merge IVirtualMemoryManager and IAddressSpaceManager

* Fix Ro loading data from the wrong process

Co-authored-by: Thog <me@thog.eu>
2020-12-02 00:23:43 +01:00

111 lines
3.5 KiB
C#

using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Memory;
using Ryujinx.HLE.HOS.Kernel.Process;
using Ryujinx.HLE.HOS.Kernel.SupervisorCall;
using Ryujinx.HLE.HOS.Kernel.Threading;
using Ryujinx.Memory;
using System;
using System.Collections.Concurrent;
using System.Threading;
namespace Ryujinx.HLE.HOS.Kernel
{
class KernelContext : IDisposable
{
public long PrivilegedProcessLowestId { get; set; } = 1;
public long PrivilegedProcessHighestId { get; set; } = 8;
public bool EnableVersionChecks { get; set; }
public bool KernelInitialized { get; }
public Switch Device { get; }
public MemoryBlock Memory { get; }
public Syscall Syscall { get; }
public SyscallHandler SyscallHandler { get; }
public KResourceLimit ResourceLimit { get; }
public KMemoryRegionManager[] MemoryRegions { get; }
public KMemoryBlockAllocator LargeMemoryBlockAllocator { get; }
public KMemoryBlockAllocator SmallMemoryBlockAllocator { get; }
public KSlabHeap UserSlabHeapPages { get; }
public KCriticalSection CriticalSection { get; }
public KScheduler Scheduler { get; }
public KTimeManager TimeManager { get; }
public KSynchronization Synchronization { get; }
public KContextIdManager ContextIdManager { get; }
public ConcurrentDictionary<long, KProcess> Processes { get; }
public ConcurrentDictionary<string, KAutoObject> AutoObjectNames { get; }
private long _kipId;
private long _processId;
private long _threadUid;
public KernelContext(Switch device, MemoryBlock memory)
{
Device = device;
Memory = memory;
Syscall = new Syscall(this);
SyscallHandler = new SyscallHandler(this);
ResourceLimit = new KResourceLimit(this);
KernelInit.InitializeResourceLimit(ResourceLimit);
MemoryRegions = KernelInit.GetMemoryRegions();
LargeMemoryBlockAllocator = new KMemoryBlockAllocator(KernelConstants.MemoryBlockAllocatorSize * 2);
SmallMemoryBlockAllocator = new KMemoryBlockAllocator(KernelConstants.MemoryBlockAllocatorSize);
UserSlabHeapPages = new KSlabHeap(
KernelConstants.UserSlabHeapBase,
KernelConstants.UserSlabHeapItemSize,
KernelConstants.UserSlabHeapSize);
CriticalSection = new KCriticalSection(this);
Scheduler = new KScheduler(this);
TimeManager = new KTimeManager();
Synchronization = new KSynchronization(this);
ContextIdManager = new KContextIdManager();
Scheduler.StartAutoPreemptionThread();
KernelInitialized = true;
Processes = new ConcurrentDictionary<long, KProcess>();
AutoObjectNames = new ConcurrentDictionary<string, KAutoObject>();
_kipId = KernelConstants.InitialKipId;
_processId = KernelConstants.InitialProcessId;
}
public long NewThreadUid()
{
return Interlocked.Increment(ref _threadUid) - 1;
}
public long NewKipId()
{
return Interlocked.Increment(ref _kipId) - 1;
}
public long NewProcessId()
{
return Interlocked.Increment(ref _processId) - 1;
}
public void Dispose()
{
Scheduler.Dispose();
TimeManager.Dispose();
}
}
}