public KernelContext( ITickSource tickSource, Switch device, MemoryBlock memory, MemorySize memorySize, MemoryArrange memoryArrange) { TickSource = tickSource; Device = device; Memory = memory; Running = true; Syscall = new Syscall(this); SyscallHandler = new SyscallHandler(this); ResourceLimit = new KResourceLimit(this); KernelInit.InitializeResourceLimit(ResourceLimit, memorySize); MemoryManager = new KMemoryManager(memorySize, memoryArrange); LargeMemoryBlockSlabManager = new KMemoryBlockSlabManager(KernelConstants.MemoryBlockAllocatorSize * 2); SmallMemoryBlockSlabManager = new KMemoryBlockSlabManager(KernelConstants.MemoryBlockAllocatorSize); UserSlabHeapPages = new KSlabHeap( KernelConstants.UserSlabHeapBase, KernelConstants.UserSlabHeapItemSize, KernelConstants.UserSlabHeapSize); memory.Commit(KernelConstants.UserSlabHeapBase - DramMemoryMap.DramBase, KernelConstants.UserSlabHeapSize); CriticalSection = new KCriticalSection(this); Schedulers = new KScheduler[KScheduler.CpuCoresCount]; PriorityQueue = new KPriorityQueue(); TimeManager = new KTimeManager(this); Synchronization = new KSynchronization(this); ContextIdManager = new KContextIdManager(); for (int core = 0; core < KScheduler.CpuCoresCount; core++) { Schedulers[core] = new KScheduler(this, core); } StartPreemptionThread(); KernelInitialized = true; Processes = new ConcurrentDictionary <ulong, KProcess>(); AutoObjectNames = new ConcurrentDictionary <string, KAutoObject>(); _kipId = KernelConstants.InitialKipId; _processId = KernelConstants.InitialProcessId; }
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 bool Reserve(LimitableResource Resource, long Amount, long Timeout) { long EndTimePoint = KTimeManager.ConvertNanosecondsToMilliseconds(Timeout); EndTimePoint += PerformanceCounter.ElapsedMilliseconds; bool Success = false; int Index = GetIndex(Resource); lock (LockObj) { long NewCurrent = Current[Index] + Amount; while (NewCurrent > Limit[Index] && Available[Index] + Amount <= Limit[Index]) { WaitingThreadsCount++; KConditionVariable.Wait(System, WaitingThreads, LockObj, Timeout); WaitingThreadsCount--; NewCurrent = Current[Index] + Amount; if (Timeout >= 0 && PerformanceCounter.ElapsedMilliseconds > EndTimePoint) { break; } } if (NewCurrent <= Limit[Index]) { Current[Index] = NewCurrent; Success = true; } } return(Success); }
public bool Reserve(LimitableResource resource, long amount, long timeout) { long endTimePoint = KTimeManager.ConvertNanosecondsToMilliseconds(timeout); endTimePoint += PerformanceCounter.ElapsedMilliseconds; bool success = false; int index = GetIndex(resource); lock (_lockObj) { long newCurrent = _current[index] + amount; while (newCurrent > _limit[index] && _available[index] + amount <= _limit[index]) { _waitingThreadsCount++; KConditionVariable.Wait(_system, _waitingThreads, _lockObj, timeout); _waitingThreadsCount--; newCurrent = _current[index] + amount; if (timeout >= 0 && PerformanceCounter.ElapsedMilliseconds > endTimePoint) { break; } } if (newCurrent <= _limit[index]) { _current[index] = newCurrent; success = true; } } return(success); }
private KernelResult GetInfo(uint id, int handle, long subId, out long value) { value = 0; switch (id) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 20: case 21: case 22: { if (subId != 0) { return(KernelResult.InvalidCombination); } KProcess currentProcess = _system.Scheduler.GetCurrentProcess(); KProcess process = currentProcess.HandleTable.GetKProcess(handle); if (process == null) { return(KernelResult.InvalidHandle); } switch (id) { case 0: value = process.Capabilities.AllowedCpuCoresMask; break; case 1: value = process.Capabilities.AllowedThreadPriosMask; break; case 2: value = (long)process.MemoryManager.AliasRegionStart; break; case 3: value = (long)(process.MemoryManager.AliasRegionEnd - process.MemoryManager.AliasRegionStart); break; case 4: value = (long)process.MemoryManager.HeapRegionStart; break; case 5: value = (long)(process.MemoryManager.HeapRegionEnd - process.MemoryManager.HeapRegionStart); break; case 6: value = (long)process.GetMemoryCapacity(); break; case 7: value = (long)process.GetMemoryUsage(); break; case 12: value = (long)process.MemoryManager.GetAddrSpaceBaseAddr(); break; case 13: value = (long)process.MemoryManager.GetAddrSpaceSize(); break; case 14: value = (long)process.MemoryManager.StackRegionStart; break; case 15: value = (long)(process.MemoryManager.StackRegionEnd - process.MemoryManager.StackRegionStart); break; case 16: value = (long)process.PersonalMmHeapPagesCount * KMemoryManager.PageSize; break; case 17: if (process.PersonalMmHeapPagesCount != 0) { value = process.MemoryManager.GetMmUsedPages() * KMemoryManager.PageSize; } break; case 18: value = process.TitleId; break; case 20: value = (long)process.UserExceptionContextAddress; break; case 21: value = (long)process.GetMemoryCapacityWithoutPersonalMmHeap(); break; case 22: value = (long)process.GetMemoryUsageWithoutPersonalMmHeap(); break; } break; } case 8: { if (handle != 0) { return(KernelResult.InvalidHandle); } if (subId != 0) { return(KernelResult.InvalidCombination); } value = _system.Scheduler.GetCurrentProcess().Debug ? 1 : 0; break; } case 9: { if (handle != 0) { return(KernelResult.InvalidHandle); } if (subId != 0) { return(KernelResult.InvalidCombination); } KProcess currentProcess = _system.Scheduler.GetCurrentProcess(); if (currentProcess.ResourceLimit != null) { KHandleTable handleTable = currentProcess.HandleTable; KResourceLimit resourceLimit = currentProcess.ResourceLimit; KernelResult result = handleTable.GenerateHandle(resourceLimit, out int resLimHandle); if (result != KernelResult.Success) { return(result); } value = (uint)resLimHandle; } break; } case 10: { if (handle != 0) { return(KernelResult.InvalidHandle); } int currentCore = _system.Scheduler.GetCurrentThread().CurrentCore; if (subId != -1 && subId != currentCore) { return(KernelResult.InvalidCombination); } value = _system.Scheduler.CoreContexts[currentCore].TotalIdleTimeTicks; break; } case 11: { if (handle != 0) { return(KernelResult.InvalidHandle); } if ((ulong)subId > 3) { return(KernelResult.InvalidCombination); } KProcess currentProcess = _system.Scheduler.GetCurrentProcess(); value = currentProcess.RandomEntropy[subId]; break; } case 0xf0000002u: { if (subId < -1 || subId > 3) { return(KernelResult.InvalidCombination); } KThread thread = _system.Scheduler.GetCurrentProcess().HandleTable.GetKThread(handle); if (thread == null) { return(KernelResult.InvalidHandle); } KThread currentThread = _system.Scheduler.GetCurrentThread(); int currentCore = currentThread.CurrentCore; if (subId != -1 && subId != currentCore) { return(KernelResult.Success); } KCoreContext coreContext = _system.Scheduler.CoreContexts[currentCore]; long timeDelta = PerformanceCounter.ElapsedMilliseconds - coreContext.LastContextSwitchTime; if (subId != -1) { value = KTimeManager.ConvertMillisecondsToTicks(timeDelta); } else { long totalTimeRunning = thread.TotalTimeRunning; if (thread == currentThread) { totalTimeRunning += timeDelta; } value = KTimeManager.ConvertMillisecondsToTicks(totalTimeRunning); } break; } default: return(KernelResult.InvalidEnumValue); } return(KernelResult.Success); }
public bool Reserve(LimitableResource Resource, long Amount) { return(Reserve(Resource, Amount, KTimeManager.ConvertMillisecondsToNanoseconds(Time10SecondsMs))); }
private KernelResult GetInfo(uint Id, int Handle, long SubId, out long Value) { Value = 0; switch (Id) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 20: case 21: case 22: { if (SubId != 0) { return(KernelResult.InvalidCombination); } KProcess CurrentProcess = System.Scheduler.GetCurrentProcess(); KProcess Process = CurrentProcess.HandleTable.GetKProcess(Handle); if (Process == null) { return(KernelResult.InvalidHandle); } switch (Id) { case 0: Value = Process.Capabilities.AllowedCpuCoresMask; break; case 1: Value = Process.Capabilities.AllowedThreadPriosMask; break; case 2: Value = (long)Process.MemoryManager.AliasRegionStart; break; case 3: Value = (long)(Process.MemoryManager.AliasRegionEnd - Process.MemoryManager.AliasRegionStart); break; case 4: Value = (long)Process.MemoryManager.HeapRegionStart; break; case 5: Value = (long)(Process.MemoryManager.HeapRegionEnd - Process.MemoryManager.HeapRegionStart); break; case 6: Value = (long)Process.GetMemoryCapacity(); break; case 7: Value = (long)Process.GetMemoryUsage(); break; case 12: Value = (long)Process.MemoryManager.GetAddrSpaceBaseAddr(); break; case 13: Value = (long)Process.MemoryManager.GetAddrSpaceSize(); break; case 14: Value = (long)Process.MemoryManager.StackRegionStart; break; case 15: Value = (long)(Process.MemoryManager.StackRegionEnd - Process.MemoryManager.StackRegionStart); break; case 16: Value = (long)Process.PersonalMmHeapPagesCount * KMemoryManager.PageSize; break; case 17: if (Process.PersonalMmHeapPagesCount != 0) { Value = Process.MemoryManager.GetMmUsedPages() * KMemoryManager.PageSize; } break; case 18: Value = Process.TitleId; break; case 20: Value = (long)Process.UserExceptionContextAddress; break; case 21: Value = (long)Process.GetMemoryCapacityWithoutPersonalMmHeap(); break; case 22: Value = (long)Process.GetMemoryUsageWithoutPersonalMmHeap(); break; } break; } case 8: { if (Handle != 0) { return(KernelResult.InvalidHandle); } if (SubId != 0) { return(KernelResult.InvalidCombination); } Value = System.Scheduler.GetCurrentProcess().Debug ? 1 : 0; break; } case 9: { if (Handle != 0) { return(KernelResult.InvalidHandle); } if (SubId != 0) { return(KernelResult.InvalidCombination); } KProcess CurrentProcess = System.Scheduler.GetCurrentProcess(); if (CurrentProcess.ResourceLimit != null) { KHandleTable HandleTable = CurrentProcess.HandleTable; KResourceLimit ResourceLimit = CurrentProcess.ResourceLimit; KernelResult Result = HandleTable.GenerateHandle(ResourceLimit, out int ResLimHandle); if (Result != KernelResult.Success) { return(Result); } Value = (uint)ResLimHandle; } break; } case 10: { if (Handle != 0) { return(KernelResult.InvalidHandle); } int CurrentCore = System.Scheduler.GetCurrentThread().CurrentCore; if (SubId != -1 && SubId != CurrentCore) { return(KernelResult.InvalidCombination); } Value = System.Scheduler.CoreContexts[CurrentCore].TotalIdleTimeTicks; break; } case 11: { if (Handle != 0) { return(KernelResult.InvalidHandle); } if ((ulong)SubId > 3) { return(KernelResult.InvalidCombination); } KProcess CurrentProcess = System.Scheduler.GetCurrentProcess(); Value = CurrentProcess.RandomEntropy[SubId]; break; } case 0xf0000002u: { if (SubId < -1 || SubId > 3) { return(KernelResult.InvalidCombination); } KThread Thread = System.Scheduler.GetCurrentProcess().HandleTable.GetKThread(Handle); if (Thread == null) { return(KernelResult.InvalidHandle); } KThread CurrentThread = System.Scheduler.GetCurrentThread(); int CurrentCore = CurrentThread.CurrentCore; if (SubId != -1 && SubId != CurrentCore) { return(KernelResult.Success); } KCoreContext CoreContext = System.Scheduler.CoreContexts[CurrentCore]; long TimeDelta = PerformanceCounter.ElapsedMilliseconds - CoreContext.LastContextSwitchTime; if (SubId != -1) { Value = KTimeManager.ConvertMillisecondsToTicks(TimeDelta); } else { long TotalTimeRunning = Thread.TotalTimeRunning; if (Thread == CurrentThread) { TotalTimeRunning += TimeDelta; } Value = KTimeManager.ConvertMillisecondsToTicks(TotalTimeRunning); } break; } default: return(KernelResult.InvalidEnumValue); } return(KernelResult.Success); }
private KernelResult CreateThread( ulong entrypoint, ulong argsPtr, ulong stackTop, int priority, int cpuCore, out int handle) { handle = 0; KProcess currentProcess = _system.Scheduler.GetCurrentProcess(); if (cpuCore == -2) { cpuCore = currentProcess.DefaultCpuCore; } if ((uint)cpuCore >= KScheduler.CpuCoresCount || !currentProcess.IsCpuCoreAllowed(cpuCore)) { return(KernelResult.InvalidCpuCore); } if ((uint)priority >= KScheduler.PrioritiesCount || !currentProcess.IsPriorityAllowed(priority)) { return(KernelResult.InvalidPriority); } long timeout = KTimeManager.ConvertMillisecondsToNanoseconds(100); if (currentProcess.ResourceLimit != null && !currentProcess.ResourceLimit.Reserve(LimitableResource.Thread, 1, timeout)) { return(KernelResult.ResLimitExceeded); } KThread thread = new KThread(_system); KernelResult result = currentProcess.InitializeThread( thread, entrypoint, argsPtr, stackTop, priority, cpuCore); if (result != KernelResult.Success) { currentProcess.ResourceLimit?.Release(LimitableResource.Thread, 1); return(result); } result = _process.HandleTable.GenerateHandle(thread, out handle); if (result != KernelResult.Success) { thread.Terminate(); currentProcess.ResourceLimit?.Release(LimitableResource.Thread, 1); } return(result); }
private KernelResult CreateThread( ulong Entrypoint, ulong ArgsPtr, ulong StackTop, int Priority, int CpuCore, out int Handle) { Handle = 0; KProcess CurrentProcess = System.Scheduler.GetCurrentProcess(); if (CpuCore == -2) { CpuCore = CurrentProcess.DefaultCpuCore; } if ((uint)CpuCore >= KScheduler.CpuCoresCount || !CurrentProcess.IsCpuCoreAllowed(CpuCore)) { return(KernelResult.InvalidCpuCore); } if ((uint)Priority >= KScheduler.PrioritiesCount || !CurrentProcess.IsPriorityAllowed(Priority)) { return(KernelResult.InvalidPriority); } long Timeout = KTimeManager.ConvertMillisecondsToNanoseconds(100); if (CurrentProcess.ResourceLimit != null && !CurrentProcess.ResourceLimit.Reserve(LimitableResource.Thread, 1, Timeout)) { return(KernelResult.ResLimitExceeded); } KThread Thread = new KThread(System); KernelResult Result = CurrentProcess.InitializeThread( Thread, Entrypoint, ArgsPtr, StackTop, Priority, CpuCore); if (Result != KernelResult.Success) { CurrentProcess.ResourceLimit?.Release(LimitableResource.Thread, 1); return(Result); } Result = Process.HandleTable.GenerateHandle(Thread, out Handle); if (Result != KernelResult.Success) { Thread.Terminate(); CurrentProcess.ResourceLimit?.Release(LimitableResource.Thread, 1); } return(Result); }