KeStartThread

NTSTATUS __fastcall KeStartThread(_ETHREAD *Thread, _GROUP_AFFINITY *GroupAffinity, UINT64 *a3){
  _GROUP_AFFINITY *p_Affinity; 
  _KNODE *v6; 
  unsigned __int16 ThreadSeed; 
  _ETHREAD *CurrentThread; 
  _EPROCESS *Process; 
  UINT16 v10; 
  UINT64 *v11; 
  char BasePriority; 
  __int64 v13; 
  unsigned int v14; 
  _LIST_ENTRY *p_ThreadListHead; 
  _KPRCB *v16; 
  int QuantumReset; 
  int v18; 
  unsigned __int64 v19; 
  _LIST_ENTRY *Blink; 
  _LIST_ENTRY *p_ThreadListEntry; 
  NTSTATUS result; 
  char Priority; 
  char v24; 
  _LIST_ENTRY **v25; 
  _LIST_ENTRY *p_ProcessListEntry; 
  UINT64 Group; 
  unsigned __int64 v28; 
  char v29; 
  char v30; 
  UINT64 AltSeed; 
  __int64 CurrentIrql; 
  __int64 v33; 
  _KLOCK_QUEUE_HANDLE LockQueue; 
  _GROUP_AFFINITY Affinity; 

  HIDWORD(AltSeed) = 0;
  v33 = 0i64;
  p_Affinity = GroupAffinity;
  Affinity = 0i64;
  memset(&LockQueue, 0, sizeof(LockQueue));
  if( !a3 && GroupAffinity && GroupAffinity->Mask )
  {
    v6 = KeSelectNodeForAffinity(GroupAffinity);
    v30 = v29;
    ThreadSeed = v6->ThreadSeed;
  }
  else
  {
    v6 = 0i64;
    v30 = 1;
    ThreadSeed = 0;
  }
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  Process = Thread->Tcb.ApcState.Process;
  *(&Thread->Tcb.MiscFlags + 1) ^= (*(&Thread->Tcb.MiscFlags + 1) ^ (4 * Process->Pcb._bf_0)) & 8;
  CurrentIrql = KeGetCurrentIrql();
  __writecr8(2ui64);
  ExAcquireSpinLockExclusiveAtDpcLevel((INT64 *)&Process->Pcb.ProcessLock);
  BasePriority = Process->Pcb.BasePriority;
  Thread->Tcb.BasePriority = BasePriority;
  Thread->Tcb.Priority = BasePriority;
  if( p_Affinity )
  {
    Group = p_Affinity->Group;
    v28 = Process->Pcb.Affinity.Bitmap[Group];
    if( !v28 || (v28 & p_Affinity->Mask) != p_Affinity->Mask )
      KiExtendProcessAffinity(&Process->Pcb, Group);
    if( !p_Affinity->Mask )
      p_Affinity->Mask = Process->Pcb.Affinity.Bitmap[p_Affinity->Group];
  }
  else
  {
    if( Process == CurrentThread->Tcb.Process )
    {
      Affinity.Group = CurrentThread->Tcb.UserAffinity.Group;
      Affinity.Mask = Process->Pcb.Affinity.Bitmap[Affinity.Group];
    }
    else
    {
      KeFirstGroupAffinityEx(&Affinity, (_BYTE)Process + 80, v10, v11);
    }
    p_Affinity = &Affinity;
  }
  Thread->Tcb.Affinity.Group = p_Affinity->Group;
  Thread->Tcb.Affinity.Mask = p_Affinity->Mask;
  Thread->Tcb.UserAffinity.Group = p_Affinity->Group;
  Thread->Tcb.UserAffinity.Mask = p_Affinity->Mask;
  KiUpdateNodeAffinitizedFlag(&Thread->Tcb);
  if( a3 )
  {
    v14 = *(_DWORD *)a3;
  }
  else
  {
    if( !v6 )
    {
      v13 = p_Affinity->Group;
      ThreadSeed = Process->Pcb.ThreadSeed[v13];
      v6 = (_KNODE *)KeNodeBlock[Process->Pcb.IdealNode[v13]];
      HIDWORD(AltSeed) = Process->Pcb.IdealProcessor[v13];
      v33 = (__int64)&AltSeed + 4;
    }
    p_Affinity->Mask &= v6->Affinity.Mask;
    LOWORD(AltSeed) = ThreadSeed;
    v14 = (unsigned __int16)KeSelectIdealProcessor(v6, p_Affinity, &AltSeed);
    if( v30 )
      Process->Pcb.ThreadSeed[p_Affinity->Group] = AltSeed;
  }
  Thread->Tcb.UserIdealProcessor = v14;
  p_ThreadListHead = &Process->Pcb.ThreadListHead;
  Thread->Tcb.IdealProcessor = v14;
  v16 = *(&KiProcessorBlock + v14);
  if( p_ThreadListHead->Flink == p_ThreadListHead && Process != (_EPROCESS *)&KiInitialProcess )
  {
    LockQueue.LockQueue.Next = 0i64;
    LockQueue.LockQueue.Lock = &KiProcessListLock;
    KxAcquireQueuedSpinLock(&LockQueue.LockQueue, &KiProcessListLock);
    v25 = (_LIST_ENTRY **)qword_140C319F8;
    p_ProcessListEntry = &Process->Pcb.ProcessListEntry;
    if( *(__int64 **)qword_140C319F8 != &KiProcessListHead )
      goto LABEL_45;
    Process->Pcb.ProcessListEntry.Blink = (_LIST_ENTRY *)qword_140C319F8;
    p_ProcessListEntry->Flink = (_LIST_ENTRY *)&KiProcessListHead;
    *v25 = p_ProcessListEntry;
    qword_140C319F8 = (__int64)&Process->Pcb.ProcessListEntry;
    KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
  }
  *(&Thread->Tcb.MiscFlags + 1) ^= (*(&Thread->Tcb.MiscFlags + 1) ^ (Process->Pcb._bf_0 << 6)) & 0x100;
  QuantumReset = (unsigned __int8)Process->Pcb.QuantumReset;
  v18 = *(&Thread->Tcb.MiscFlags + 1);
  Thread->Tcb.SchedulerApc.SpareByte1 = QuantumReset;
  v19 = (unsigned int)(KiCyclesPerClockQuantum * QuantumReset);
  if( (v18 & 0x20) != 0 )
    _interlockedbittestandreset((volatile signed __int32 *)&Thread->Tcb.116 + 1, 5u);
  Thread->Tcb.QuantumTarget = v19;
  KiAcquireKobjectLockSafe(Process);
  Blink = Process->Pcb.ThreadListHead.Blink;
  p_ThreadListEntry = &Thread->Tcb.ThreadListEntry;
  if( Blink->Flink != p_ThreadListHead )
LABEL_45:
    __fastfail(3u);
  p_ThreadListEntry->Flink = p_ThreadListHead;
  Thread->Tcb.ThreadListEntry.Blink = Blink;
  Blink->Flink = p_ThreadListEntry;
  Process->Pcb.ThreadListHead.Blink = p_ThreadListEntry;
  _InterlockedAnd((volatile signed __int32 *)Process, 0xFFFFFF7F);
  if( (Process->Pcb._bf_0 & 8) != 0 )
    KiFreezeSingleThread(KeGetCurrentPrcb(), &Thread->Tcb);
  Thread->Tcb.SchedulingGroup = Process->Pcb.SchedulingGroup;
  if( Process->Pcb.SchedulingGroup )
    _interlockedbittestandset((volatile signed __int32 *)Thread, 0x12u);
  KiUpdateSharedReadyQueueAffinityThread(v16, &Thread->Tcb);
  if( Thread->Tcb.Process->Vm.Instance.Flags.MemoryPriority == 2
    && !Thread->Tcb.PriorityDecrement
    && (*(&Thread->Tcb.MiscFlags + 1) & 8) == 0 )
  {
    Priority = Thread->Tcb.Priority;
    if( Priority > 0 )
    {
      v24 = PsPrioritySeparation + Thread->Tcb.BasePriority;
      if( v24 >= 16 )
        v24 = 15;
      if( v24 > Priority )
      {
        Thread->Tcb.PriorityDecrement = (v24 - Priority) & 0xF;
        KiUpdateThreadPriority(0i64, &Thread->Tcb, (unsigned int)v24, 0);
        KiUpdateSharedReadyQueueAffinityThread(0i64, &Thread->Tcb);
      }
    }
  }
  if( (Thread->Tcb._bf_0 & 0x400) == 0 )
    Thread->Tcb.ThreadTimerDelay = Process->Pcb.ProcessTimerDelay;
  ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)&Process->Pcb.ProcessLock);
  result = (unsigned __int8)CurrentIrql;
  __writecr8((unsigned __int8)CurrentIrql);
  if( (xmmword_140CFB490 & 0x8000000) != 0 )
  {
    EtwTraceIdealProcessor((__int64)Thread, 0x546u, -1, v14);
    if( (xmmword_140CFB490 & 0x8000000) != 0 )
      EtwTraceIdealProcessor((__int64)Thread, 0x547u, -1, v14);
  }
  _InterlockedExchangeAdd(&Process->Pcb.StackCount.Value, 8u);
  return result;
}

Referenced by:

KiInitializeIdleThread
PspInsertThread