MCPcopy Create free account
hub / github.com/FEX-Emu/FEX / ThreadTerm

Function ThreadTerm

Source/Windows/ARM64EC/Module.cpp:1012–1064  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1010}
1011
1012NTSTATUS ThreadTerm(HANDLE Thread, LONG ExitCode) {
1013 if (!FEX::Windows::ValidateHandleAccess(Thread, THREAD_TERMINATE)) {
1014 return STATUS_ACCESS_DENIED;
1015 }
1016
1017 auto ThreadDup = FEX::Windows::DupHandle(Thread, THREAD_QUERY_INFORMATION | THREAD_SUSPEND_RESUME);
1018
1019 THREAD_BASIC_INFORMATION Info;
1020 if (auto Err = NtQueryInformationThread(*ThreadDup, ThreadBasicInformation, &Info, sizeof(Info), nullptr); Err) {
1021 return Err;
1022 }
1023
1024 const auto ThreadTID = reinterpret_cast<uint64_t>(Info.ClientId.UniqueThread);
1025 bool Self = ThreadTID == GetCurrentThreadId();
1026 if (!Self) {
1027 CONTEXT TmpContext;
1028 // If we are suspending a thread that isn't ourselves, try to suspend it first so we know internal JIT locks aren't being held.
1029 NtSuspendThread(*ThreadDup, NULL);
1030 // This will wait for the thread to be suspended
1031 NtGetContextThread(*ThreadDup, &TmpContext);
1032 }
1033
1034 const auto [Err, CPUArea] = GetThreadCPUArea(*ThreadDup);
1035 if (Err) {
1036 return Err;
1037 }
1038
1039 {
1040 std::scoped_lock Lock(ThreadCreationMutex);
1041 auto it = Threads.find(ThreadTID);
1042 if (it == Threads.end()) {
1043 // Thread already terminated
1044 return STATUS_SUCCESS;
1045 }
1046
1047 Threads.erase(it);
1048 if (StatAllocHandler) {
1049 StatAllocHandler->DeallocateSlot(CPUArea.ThreadState()->ThreadStats);
1050 }
1051 }
1052 auto ThreadState = CPUArea.ThreadState();
1053
1054 // GDT and LDT are mirrored, only free one.
1055 delete[] ThreadState->CurrentFrame->State.segment_arrays[FEXCore::Core::CPUState::SEGMENT_ARRAY_INDEX_GDT];
1056
1057 FEX::Windows::CallRetStack::DestroyThread(ThreadState);
1058 CTX->DestroyThread(ThreadState);
1059 ::VirtualFree(reinterpret_cast<void*>(CPUArea.EmulatorStackLimit()), 0, MEM_RELEASE);
1060 if (ThreadTID == GetCurrentThreadId()) {
1061 FEX::Windows::DeinitCRTThread();
1062 }
1063 return STATUS_SUCCESS;
1064}
1065
1066BOOLEAN BTCpu64IsProcessorFeaturePresent(UINT Feature) {
1067 return CPUFeatures->IsFeaturePresent(Feature) ? TRUE : FALSE;

Callers

nothing calls this directly

Calls 10

ValidateHandleAccessFunction · 0.85
DupHandleFunction · 0.85
GetThreadCPUAreaFunction · 0.85
DestroyThreadFunction · 0.85
VirtualFreeFunction · 0.85
DeinitCRTThreadFunction · 0.85
eraseMethod · 0.80
endMethod · 0.45
DeallocateSlotMethod · 0.45
DestroyThreadMethod · 0.45

Tested by

no test coverage detected