public KernelResult Initialize( ulong entrypoint, ulong argsPtr, ulong stackTop, int priority, int defaultCpuCore, KProcess owner, ThreadType type = ThreadType.User) { if ((uint)type > 3) { throw new ArgumentException($"Invalid thread type \"{type}\"."); } PreferredCore = defaultCpuCore; AffinityMask |= 1L << defaultCpuCore; SchedFlags = type == ThreadType.Dummy ? ThreadSchedState.Running : ThreadSchedState.None; CurrentCore = PreferredCore; DynamicPriority = priority; BasePriority = priority; ObjSyncResult = KernelResult.ThreadNotStarted; _entrypoint = entrypoint; if (type == ThreadType.User) { if (owner.AllocateThreadLocalStorage(out _tlsAddress) != KernelResult.Success) { return(KernelResult.OutOfMemory); } TlsDramAddress = owner.MemoryManager.GetDramAddressFromVa(_tlsAddress); MemoryHelper.FillWithZeros(owner.CpuMemory, (long)_tlsAddress, KTlsPageInfo.TlsEntrySize); } bool is64Bits; if (owner != null) { Owner = owner; owner.IncrementReferenceCount(); owner.IncrementThreadCount(); is64Bits = (owner.MmuFlags & 1) != 0; } else { is64Bits = true; } Context = new CpuThread(owner.Translator, owner.CpuMemory, (long)entrypoint); bool isAarch32 = (Owner.MmuFlags & 1) == 0; Context.ThreadState.Aarch32 = isAarch32; Context.ThreadState.X0 = argsPtr; if (isAarch32) { Context.ThreadState.X13 = (uint)stackTop; } else { Context.ThreadState.X31 = stackTop; } Context.ThreadState.CntfrqEl0 = 19200000; Context.ThreadState.Tpidr = (long)_tlsAddress; owner.SubscribeThreadEventHandlers(Context); Context.WorkFinished += ThreadFinishedHandler; ThreadUid = System.GetThreadUid(); _hasBeenInitialized = true; if (owner != null) { owner.AddThread(this); if (owner.IsPaused) { System.CriticalSection.Enter(); if (ShallBeTerminated || SchedFlags == ThreadSchedState.TerminationPending) { System.CriticalSection.Leave(); return(KernelResult.Success); } _forcePauseFlags |= ThreadSchedState.ProcessPauseFlag; CombineForcePauseFlags(); System.CriticalSection.Leave(); } } return(KernelResult.Success); }