33#include < kernel/memory.h>
44#include < kernel/heap.h>
55#include < kernel/function.h>
6+ #include < os/logger.h>
7+ #include < unordered_map>
68#include " ppc_context.h"
79
810constexpr size_t PCR_SIZE = 0xAB0 ;
@@ -13,6 +15,29 @@ constexpr size_t TOTAL_SIZE = PCR_SIZE + TLS_SIZE + TEB_SIZE + STACK_SIZE;
1315
1416constexpr size_t TEB_OFFSET = PCR_SIZE + TLS_SIZE ;
1517
18+ static std::mutex g_guestThreadRegistryMutex;
19+ static std::unordered_map<uint32_t , uint32_t > g_guestThreadRegistry;
20+
21+ static void RegisterGuestThread (uint32_t guestThreadId)
22+ {
23+ std::lock_guard lock (g_guestThreadRegistryMutex);
24+ const auto [it, inserted] = g_guestThreadRegistry.emplace (
25+ guestThreadId, GuestThread::GetCurrentThreadId ());
26+ if (!inserted)
27+ {
28+ LOGFN_ERROR (
29+ " SYNC-THREAD-DUPLICATE guestThread=0x{:08X} oldHostThread=0x{:08X} newHostThread=0x{:08X}" ,
30+ guestThreadId, it->second , GuestThread::GetCurrentThreadId ());
31+ it->second = GuestThread::GetCurrentThreadId ();
32+ }
33+ }
34+
35+ static void UnregisterGuestThread (uint32_t guestThreadId)
36+ {
37+ std::lock_guard lock (g_guestThreadRegistryMutex);
38+ g_guestThreadRegistry.erase (guestThreadId);
39+ }
40+
1641GuestThreadContext::GuestThreadContext (uint32_t cpuNumber)
1742{
1843 assert (thread == nullptr );
@@ -33,10 +58,13 @@ GuestThreadContext::GuestThreadContext(uint32_t cpuNumber)
3358
3459 assert (GetPPCContext () == nullptr );
3560 SetPPCContext (ppcContext);
61+ RegisterGuestThread (ppcContext.r13 .u32 );
3662}
3763
3864GuestThreadContext::~GuestThreadContext ()
3965{
66+ UnregisterGuestThread (ppcContext.r13 .u32 );
67+ ClearPPCContext ();
4068 g_userHeap.Free (thread);
4169}
4270
@@ -71,7 +99,7 @@ static void* GuestThreadFunc(void* arg)
7199static void GuestThreadFunc (GuestThreadHandle* hThread)
72100{
73101#endif
74- hThread->suspended . wait ( true );
102+ hThread->WaitWhileSuspended ( );
75103 GuestThread::Start (hThread->params );
76104#ifdef USE_PTHREAD
77105 return nullptr ;
@@ -125,6 +153,35 @@ uint32_t GuestThreadHandle::GetThreadId() const
125153#endif
126154}
127155
156+ void GuestThreadHandle::SetSuspended (bool value)
157+ {
158+ #if defined(UNLEASHED_RECOMP_IOS_LAUNCHER)
159+ {
160+ std::lock_guard lock (suspendMutex);
161+ suspended.store (value, std::memory_order_release);
162+ }
163+ if (!value)
164+ suspendCondition.notify_all ();
165+ #else
166+ suspended.store (value, std::memory_order_release);
167+ if (!value)
168+ suspended.notify_all ();
169+ #endif
170+ }
171+
172+ void GuestThreadHandle::WaitWhileSuspended ()
173+ {
174+ #if defined(UNLEASHED_RECOMP_IOS_LAUNCHER)
175+ std::unique_lock lock (suspendMutex);
176+ suspendCondition.wait (lock, [&]
177+ {
178+ return !suspended.load (std::memory_order_acquire);
179+ });
180+ #else
181+ suspended.wait (true , std::memory_order_acquire);
182+ #endif
183+ }
184+
128185uint32_t GuestThreadHandle::Wait (uint32_t timeout)
129186{
130187 assert (timeout == INFINITE );
@@ -173,6 +230,13 @@ uint32_t GuestThread::GetCurrentThreadId()
173230#endif
174231}
175232
233+ uint32_t GuestThread::FindHostThreadId (uint32_t guestThreadId)
234+ {
235+ std::lock_guard lock (g_guestThreadRegistryMutex);
236+ const auto it = g_guestThreadRegistry.find (guestThreadId);
237+ return it != g_guestThreadRegistry.end () ? it->second : 0 ;
238+ }
239+
176240void GuestThread::SetLastError (uint32_t error)
177241{
178242 auto * thread = (char *)g_memory.Translate (GetPPCContext ()->r13 .u32 );
0 commit comments