diff options
Diffstat (limited to 'Ryujinx.HLE/HOS/Kernel/KernelContext.cs')
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/KernelContext.cs | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/Ryujinx.HLE/HOS/Kernel/KernelContext.cs b/Ryujinx.HLE/HOS/Kernel/KernelContext.cs new file mode 100644 index 00000000..feb3f9e9 --- /dev/null +++ b/Ryujinx.HLE/HOS/Kernel/KernelContext.cs @@ -0,0 +1,114 @@ +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 CountdownEvent ThreadCounter { 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(device, this); + + SyscallHandler = new SyscallHandler(this); + + ThreadCounter = new CountdownEvent(1); + + 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(); + } + } +} |