Revert to using the host to do thread suspension
This commit is contained in:
parent
4fca5c7007
commit
08ab4b9164
|
@ -132,6 +132,28 @@ xbox::ulonglong_xt LARGE_INTEGER2ULONGLONG(xbox::LARGE_INTEGER value)
|
|||
}
|
||||
|
||||
|
||||
xbox::void_xt xbox::KeResumeThreadEx
|
||||
(
|
||||
IN PKTHREAD Thread
|
||||
)
|
||||
{
|
||||
// This is only to be used to synchronize new thread creation with the thread that spawned it
|
||||
|
||||
Thread->SuspendSemaphore.Header.SignalState = 1;
|
||||
KiWaitTest(&Thread->SuspendSemaphore, 0);
|
||||
}
|
||||
|
||||
xbox::void_xt xbox::KeSuspendThreadEx
|
||||
(
|
||||
IN PKTHREAD Thread
|
||||
)
|
||||
{
|
||||
// This is only to be used to synchronize new thread creation with the thread that spawned it
|
||||
|
||||
Thread->SuspendSemaphore.Header.SignalState = 0;
|
||||
KiInsertQueueApc(&Thread->SuspendApc, 0);
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * EmuKeGetPcr()
|
||||
// * NOTE: This is a macro on the Xbox, however we implement it
|
||||
|
@ -1729,8 +1751,13 @@ XBSYSAPI EXPORTNUM(140) xbox::ulong_xt NTAPI xbox::KeResumeThread
|
|||
if (OldCount != 0) {
|
||||
--Thread->SuspendCount;
|
||||
if (Thread->SuspendCount == 0) {
|
||||
#if 0
|
||||
++Thread->SuspendSemaphore.Header.SignalState;
|
||||
KiWaitTest(&Thread->SuspendSemaphore, 0);
|
||||
#else
|
||||
const auto &nativeHandle = GetNativeHandle<true>(reinterpret_cast<PETHREAD>(Thread)->UniqueThread);
|
||||
ResumeThread(*nativeHandle);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2089,10 +2116,20 @@ XBSYSAPI EXPORTNUM(152) xbox::ulong_xt NTAPI xbox::KeSuspendThread
|
|||
if (Thread->ApcState.ApcQueueable == TRUE) {
|
||||
++Thread->SuspendCount;
|
||||
if (OldCount == 0) {
|
||||
#if 0
|
||||
if (KiInsertQueueApc(&Thread->SuspendApc, 0) == FALSE) {
|
||||
--Thread->SuspendSemaphore.Header.SignalState;
|
||||
}
|
||||
#else
|
||||
// JSRF creates a thread at 0x0013BC30 and then it attempts to continuously suspend/resume it. Unfortunately, this thread performs a never ending loop (and
|
||||
// terminates if it ever exit the loop), and never calls any kernel functions in the middle. This means that our suspend APC will never be executed and so
|
||||
// we cannot suspend such thread. Thus, we will always have to rely on the host to do the suspension, as long as we do direct execution. Note that this is
|
||||
// a general issue for all kernel APCs too.
|
||||
const auto &nativeHandle = GetNativeHandle<true>(reinterpret_cast<PETHREAD>(Thread)->UniqueThread);
|
||||
SuspendThread(*nativeHandle);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
KiUnlockDispatcherDatabase(OldIrql);
|
||||
|
|
|
@ -52,5 +52,15 @@ namespace xbox
|
|||
IN PKPROCESS Process
|
||||
);
|
||||
|
||||
xbox::void_xt KeResumeThreadEx
|
||||
(
|
||||
IN PKTHREAD Thread
|
||||
);
|
||||
|
||||
xbox::void_xt KeSuspendThreadEx
|
||||
(
|
||||
IN PKTHREAD Thread
|
||||
);
|
||||
|
||||
void_xt KeEmptyQueueApc();
|
||||
}
|
||||
|
|
|
@ -122,7 +122,6 @@ static unsigned int WINAPI PCSTProxy
|
|||
params.TlsDataSize);
|
||||
|
||||
xbox::KiExecuteKernelApc();
|
||||
eThread->Tcb.State = xbox::Running;
|
||||
|
||||
auto routine = (xbox::PKSYSTEM_ROUTINE)StartFrame->SystemRoutine;
|
||||
// Debugging notice : When the below line shows up with an Exception dialog and a
|
||||
|
@ -411,20 +410,24 @@ XBSYSAPI EXPORTNUM(255) xbox::ntstatus_xt NTAPI xbox::PsCreateSystemThreadEx
|
|||
|
||||
g_AffinityPolicy->SetAffinityXbox(handle);
|
||||
|
||||
// Wait for the initialization of the remaining thread state
|
||||
KeSuspendThreadEx(&eThread->Tcb);
|
||||
ResumeThread(handle);
|
||||
while (eThread->Tcb.State == Initialized) {
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
// Now that ThreadId is populated and affinity is changed, resume the thread (unless the guest passed CREATE_SUSPENDED), then wait until the new thread has
|
||||
// finished initialization
|
||||
if (CreateSuspended) {
|
||||
KeSuspendThread(&eThread->Tcb);
|
||||
}
|
||||
|
||||
KeResumeThreadEx(&eThread->Tcb);
|
||||
|
||||
// Log ThreadID identical to how GetCurrentThreadID() is rendered :
|
||||
EmuLog(LOG_LEVEL::DEBUG, "Created Xbox proxy thread. Handle : 0x%X, ThreadId : [0x%.4X], Native Handle : 0x%X, Native ThreadId : [0x%.4X]",
|
||||
*ThreadHandle, eThread->UniqueThread, handle, ThreadId);
|
||||
|
||||
ResumeThread(handle);
|
||||
while (eThread->Tcb.State == Initialized) {
|
||||
std::this_thread::yield();
|
||||
}
|
||||
}
|
||||
|
||||
RETURN(X_STATUS_SUCCESS);
|
||||
|
|
Loading…
Reference in New Issue