예제 #1
0
            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);
                        }
                    }
                }
            }
예제 #2
0
        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();
        }
예제 #3
0
        //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);
        }
예제 #4
0
파일: Horizon.cs 프로젝트: wacmtg/Ryujinx
        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();
            }
        }
예제 #5
0
파일: SvcThread.cs 프로젝트: mokmax/Ryujinx
        private KernelResult StartThread(int handle)
        {
            KThread thread = _process.HandleTable.GetObject <KThread>(handle);

            if (thread != null)
            {
                return(thread.Start());
            }
            else
            {
                return(KernelResult.InvalidHandle);
            }
        }
예제 #6
0
        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();
            }
        }
예제 #7
0
        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);
        }
예제 #9
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);
            }
        }
예제 #10
0
        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);
            }
        }
예제 #11
0
        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();
            }
        }
예제 #12
0
        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();
        }