public void ChangeSize(int threadNum) { bool isNew = false; lock (list) { int num = list.Count; isNew = num > threadNum; if (isNew) { for (int i = 0; i < num - threadNum; i++) { KThread t = list[0]; t.tStop = true; t.Dispose(); list.Remove(t); } } else { for (int i = 0; i < threadNum - num; i++) { KThread t = new KThread(); list.Add(t); t.Start(job); } } } }
private void CallStopModule(KModule module, int args, int argp) { if (module.ModuleStop == 0) { return; } // Create a thread KThread thread = new KThread(_kernel, module, _kernel.Partitions[2], "module_stop_thread", module.ModuleStop, 0, KThreadAttributes.User, 0x4000); _kernel.AddHandle(thread); thread.Start(( uint )args, ( uint )argp); // Setup handler so that we get the callback when the thread ends and we can kill it _kernel.Cpu.SetContextSafetyCallback(thread.ContextID, new ContextSafetyDelegate(this.KmoduleStopThreadEnd), ( int )thread.UID); Log.WriteLine(Verbosity.Verbose, Feature.Bios, "ModuleMgrForUser: starting module_stop thread with UID {0:X} for module {1}", thread.UID, module.Name); // Schedule so that our thread runs _kernel.Schedule(); }
//public static void CreateKeeperThread(string keeperThreadName, KeeperThreadHandler<null> handler, int milliumsecondSleepTime = 1000) //{ //} /// <summary> /// 创建一个守护线程定时处理逻辑 /// </summary> /// <param name="keeperThreadName">守护线程名称</param> /// <param name="handler">处理方法</param> /// <param name="o">相关对象</param> /// <param name="milliumsecondSleepTime">方法执行完成的休息时间(毫秒),默认为1000毫秒</param> public static void CreateKeeperThread(string keeperThreadName, KeeperThreadHandler <object> handler, object o, int milliumsecondSleepTime = 1000) { if (keeperThreadName == "" || handler == null) { throw new ArgumentException(); } KeeperJob <object> j = new KeeperJob <object>(); j.handler = handler; j.obj = o; j.sleepTime = milliumsecondSleepTime; KThread t = new KThread(); lock (dicThread) { if (dicThread.ContainsKey(keeperThreadName)) { throw new ArgumentException("keeperThreadName exist"); } dicThread.Add(keeperThreadName, t); } t.Start(j); }
protected virtual void Dispose(bool disposing) { if (!_isDisposed && disposing) { _isDisposed = true; KProcess terminationProcess = new KProcess(KernelContext); KThread terminationThread = new KThread(KernelContext); terminationThread.Initialize(0, 0, 0, 3, 0, terminationProcess, ThreadType.Kernel, () => { // Force all threads to exit. lock (KernelContext.Processes) { // Terminate application. foreach (KProcess process in KernelContext.Processes.Values.Where(x => x.Flags.HasFlag(ProcessCreationFlags.IsApplication))) { process.Terminate(); } // The application existed, now surface flinger can exit too. SurfaceFlinger.Dispose(); // Terminate HLE services (must be done after the application is already terminated, // otherwise the application will receive errors due to service termination. foreach (KProcess process in KernelContext.Processes.Values.Where(x => !x.Flags.HasFlag(ProcessCreationFlags.IsApplication))) { process.Terminate(); } } // Exit ourself now! KernelStatic.GetCurrentThread().Exit(); }); terminationThread.Start(); // Wait until the thread is actually started. while (terminationThread.HostThread.ThreadState == ThreadState.Unstarted) { Thread.Sleep(10); } // Wait until the termination thread is done terminating all the other threads. terminationThread.HostThread.Join(); // Destroy nvservices channels as KThread could be waiting on some user events. // This is safe as KThread that are likely to call ioctls are going to be terminated by the post handler hook on the SVC facade. INvDrvServices.Destroy(); AudioManager.Dispose(); AudioOutputManager.Dispose(); AudioInputManager.Dispose(); AudioRendererManager.Dispose(); KernelContext.Dispose(); } }
private KernelResult StartThread(int handle) { KThread thread = _process.HandleTable.GetObject <KThread>(handle); if (thread != null) { return(thread.Start()); } else { return(KernelResult.InvalidHandle); } }
protected virtual void Dispose(bool disposing) { if (!_isDisposed && disposing) { ConfigurationState.Instance.System.EnableDockedMode.Event -= OnDockedModeChange; _isDisposed = true; SurfaceFlinger.Dispose(); KProcess terminationProcess = new KProcess(KernelContext); KThread terminationThread = new KThread(KernelContext); terminationThread.Initialize(0, 0, 0, 3, 0, terminationProcess, ThreadType.Kernel, () => { // Force all threads to exit. lock (KernelContext.Processes) { foreach (KProcess process in KernelContext.Processes.Values) { process.Terminate(); } } // Exit ourself now! KernelContext.Scheduler.ExitThread(terminationThread); KernelContext.Scheduler.GetCurrentThread().Exit(); KernelContext.Scheduler.RemoveThread(terminationThread); }); terminationThread.Start(); // Wait until the thread is actually started. while (terminationThread.HostThread.ThreadState == ThreadState.Unstarted) { Thread.Sleep(10); } // Wait until the termination thread is done terminating all the other threads. terminationThread.HostThread.Join(); // Destroy nvservices channels as KThread could be waiting on some user events. // This is safe as KThread that are likely to call ioctls are going to be terminated by the post handler hook on the SVC facade. INvDrvServices.Destroy(); AudioRendererManager.Dispose(); KernelContext.Dispose(); } }
protected virtual void Dispose(bool disposing) { if (!_isDisposed && disposing) { ConfigurationState.Instance.System.EnableDockedMode.Event -= OnDockedModeChange; _isDisposed = true; SurfaceFlinger.Dispose(); KProcess terminationProcess = new KProcess(KernelContext); KThread terminationThread = new KThread(KernelContext); terminationThread.Initialize(0, 0, 0, 3, 0, terminationProcess, ThreadType.Kernel, () => { // Force all threads to exit. lock (KernelContext.Processes) { foreach (KProcess process in KernelContext.Processes.Values) { process.Terminate(); } } // Exit ourself now! KernelContext.Scheduler.ExitThread(terminationThread); KernelContext.Scheduler.GetCurrentThread().Exit(); KernelContext.Scheduler.RemoveThread(terminationThread); }); terminationThread.Start(); // Destroy nvservices channels as KThread could be waiting on some user events. // This is safe as KThread that are likely to call ioctls are going to be terminated by the post handler hook on the SVC facade. INvDrvServices.Destroy(); // This is needed as the IPC Dummy KThread is also counted in the ThreadCounter. KernelContext.ThreadCounter.Signal(); // It's only safe to release resources once all threads // have exited. KernelContext.ThreadCounter.Signal(); KernelContext.ThreadCounter.Wait(); AudioRendererManager.Dispose(); KernelContext.Dispose(); } }
// SDK location: /user/pspthreadman.h:188 // SDK declaration: int sceKernelStartThread(SceUID thid, SceSize arglen, void *argp); public int sceKernelStartThread(int thid, int arglen, int argp) { KThread thread = _kernel.GetHandle <KThread>(thid); if (thread == null) { return(-1); } Log.WriteLine(Verbosity.Normal, Feature.Bios, "sceKernelStartThread: starting thread {0:X} {1}", thread.UID, thread.Name); thread.Start(( uint )arglen, ( uint )argp); _kernel.Schedule(); return(0); }
private KernelResult StartThread(int handle) { KThread thread = _process.HandleTable.GetKThread(handle); if (thread != null) { thread.IncrementReferenceCount(); KernelResult result = thread.Start(); if (result == KernelResult.Success) { thread.IncrementReferenceCount(); } thread.DecrementReferenceCount(); return(result); } else { return(KernelResult.InvalidHandle); } }
public KernelResult Start(int mainThreadPriority, ulong stackSize) { lock (_processLock) { if (State > ProcessState.CreatedAttached) { return(KernelResult.InvalidState); } if (ResourceLimit != null && !ResourceLimit.Reserve(LimitableResource.Thread, 1)) { return(KernelResult.ResLimitExceeded); } KResourceLimit threadResourceLimit = ResourceLimit; KResourceLimit memoryResourceLimit = null; if (_mainThreadStackSize != 0) { throw new InvalidOperationException("Trying to start a process with a invalid state!"); } ulong stackSizeRounded = BitUtils.AlignUp(stackSize, KMemoryManager.PageSize); ulong neededSize = stackSizeRounded + _imageSize; // Check if the needed size for the code and the stack will fit on the // memory usage capacity of this Process. Also check for possible overflow // on the above addition. if (neededSize > _memoryUsageCapacity || neededSize < stackSizeRounded) { threadResourceLimit?.Release(LimitableResource.Thread, 1); return(KernelResult.OutOfMemory); } if (stackSizeRounded != 0 && ResourceLimit != null) { memoryResourceLimit = ResourceLimit; if (!memoryResourceLimit.Reserve(LimitableResource.Memory, stackSizeRounded)) { threadResourceLimit?.Release(LimitableResource.Thread, 1); return(KernelResult.ResLimitExceeded); } } KernelResult result; KThread mainThread = null; ulong stackTop = 0; void CleanUpForError() { HandleTable.Destroy(); mainThread?.DecrementReferenceCount(); if (_mainThreadStackSize != 0) { ulong stackBottom = stackTop - _mainThreadStackSize; ulong stackPagesCount = _mainThreadStackSize / KMemoryManager.PageSize; MemoryManager.UnmapForKernel(stackBottom, stackPagesCount, MemoryState.Stack); _mainThreadStackSize = 0; } memoryResourceLimit?.Release(LimitableResource.Memory, stackSizeRounded); threadResourceLimit?.Release(LimitableResource.Thread, 1); } if (stackSizeRounded != 0) { ulong stackPagesCount = stackSizeRounded / KMemoryManager.PageSize; ulong regionStart = MemoryManager.StackRegionStart; ulong regionSize = MemoryManager.StackRegionEnd - regionStart; ulong regionPagesCount = regionSize / KMemoryManager.PageSize; result = MemoryManager.AllocateOrMapPa( stackPagesCount, KMemoryManager.PageSize, 0, false, regionStart, regionPagesCount, MemoryState.Stack, KMemoryPermission.ReadAndWrite, out ulong stackBottom); if (result != KernelResult.Success) { CleanUpForError(); return(result); } _mainThreadStackSize += stackSizeRounded; stackTop = stackBottom + stackSizeRounded; } ulong heapCapacity = _memoryUsageCapacity - _mainThreadStackSize - _imageSize; result = MemoryManager.SetHeapCapacity(heapCapacity); if (result != KernelResult.Success) { CleanUpForError(); return(result); } HandleTable = new KHandleTable(KernelContext); result = HandleTable.Initialize(Capabilities.HandleTableSize); if (result != KernelResult.Success) { CleanUpForError(); return(result); } mainThread = new KThread(KernelContext); result = mainThread.Initialize( _entrypoint, 0, stackTop, mainThreadPriority, DefaultCpuCore, this, ThreadType.User, _customThreadStart); if (result != KernelResult.Success) { CleanUpForError(); return(result); } result = HandleTable.GenerateHandle(mainThread, out int mainThreadHandle); if (result != KernelResult.Success) { CleanUpForError(); return(result); } mainThread.SetEntryArguments(0, mainThreadHandle); ProcessState oldState = State; ProcessState newState = State != ProcessState.Created ? ProcessState.Attached : ProcessState.Started; SetState(newState); result = mainThread.Start(); if (result != KernelResult.Success) { SetState(oldState); CleanUpForError(); } if (result == KernelResult.Success) { mainThread.IncrementReferenceCount(); } mainThread.DecrementReferenceCount(); return(result); } }
protected virtual void Dispose(bool disposing) { if (!_isDisposed && disposing) { _isDisposed = true; // "Soft" stops AudioRenderer and AudioManager to avoid some sound between resume and stop. if (IsPaused) { AudioManager.StopUpdates(); TogglePauseEmulation(false); AudioRendererManager.StopSendingCommands(); } KProcess terminationProcess = new KProcess(KernelContext); KThread terminationThread = new KThread(KernelContext); terminationThread.Initialize(0, 0, 0, 3, 0, terminationProcess, ThreadType.Kernel, () => { // Force all threads to exit. lock (KernelContext.Processes) { // Terminate application. foreach (KProcess process in KernelContext.Processes.Values.Where(x => x.Flags.HasFlag(ProcessCreationFlags.IsApplication))) { process.Terminate(); process.DecrementReferenceCount(); } // The application existed, now surface flinger can exit too. SurfaceFlinger.Dispose(); // Terminate HLE services (must be done after the application is already terminated, // otherwise the application will receive errors due to service termination). foreach (KProcess process in KernelContext.Processes.Values.Where(x => !x.Flags.HasFlag(ProcessCreationFlags.IsApplication))) { process.Terminate(); process.DecrementReferenceCount(); } KernelContext.Processes.Clear(); } // Exit ourself now! KernelStatic.GetCurrentThread().Exit(); }); terminationThread.Start(); // Wait until the thread is actually started. while (terminationThread.HostThread.ThreadState == ThreadState.Unstarted) { Thread.Sleep(10); } // Wait until the termination thread is done terminating all the other threads. terminationThread.HostThread.Join(); // Destroy nvservices channels as KThread could be waiting on some user events. // This is safe as KThread that are likely to call ioctls are going to be terminated by the post handler hook on the SVC facade. INvDrvServices.Destroy(); AudioManager.Dispose(); AudioOutputManager.Dispose(); AudioInputManager.Dispose(); AudioRendererManager.Dispose(); LibHacHorizonManager.AmClient.Fs.UnregisterProgram(LibHacHorizonManager.ApplicationClient.Os.GetCurrentProcessId().Value); KernelContext.Dispose(); } }
private void CallStopModule( KModule module, int args, int argp ) { if( module.ModuleStop == 0 ) return; // Create a thread KThread thread = new KThread( _kernel, module, _kernel.Partitions[ 2 ], "module_stop_thread", module.ModuleStop, 0, KThreadAttributes.User, 0x4000 ); _kernel.AddHandle( thread ); thread.Start( ( uint )args, ( uint )argp ); // Setup handler so that we get the callback when the thread ends and we can kill it _kernel.Cpu.SetContextSafetyCallback( thread.ContextID, new ContextSafetyDelegate( this.KmoduleStopThreadEnd ), ( int )thread.UID ); Log.WriteLine( Verbosity.Verbose, Feature.Bios, "ModuleMgrForUser: starting module_stop thread with UID {0:X} for module {1}", thread.UID, module.Name ); // Schedule so that our thread runs _kernel.Schedule(); }