77#include " GcRegCapture.h"
88#include < hx/Unordered.h>
99#include < mutex>
10+ #include < condition_variable>
1011
1112#ifdef EMSCRIPTEN
1213 #include < emscripten/stack.h>
@@ -572,23 +573,12 @@ struct BlockDataInfo *gBlockStack = 0;
572573typedef hx::QuickVec<hx::Object *> ObjectStack;
573574
574575
575- typedef HxMutex ThreadPoolLock ;
576+ static std::recursive_mutex sThreadPoolLock ;
576577
577- static ThreadPoolLock sThreadPoolLock ;
578-
579- #if !defined(HX_WINDOWS) && !defined(EMSCRIPTEN) && \
580- !defined (__SNC__) && !defined (__ORBIS__)
581- #define HX_GC_PTHREADS
582- typedef pthread_cond_t ThreadPoolSignal;
583- inline void WaitThreadLocked (ThreadPoolSignal &ioSignal)
578+ inline void WaitThreadLocked (std::condition_variable_any* ioSignal)
584579{
585- pthread_cond_wait (&ioSignal, sThreadPoolLock . mMutex );
580+ ioSignal-> wait ( sThreadPoolLock );
586581}
587- #else
588- typedef HxSemaphore ThreadPoolSignal;
589- #endif
590-
591- typedef TAutoLock<ThreadPoolLock> ThreadPoolAutoLock;
592582
593583// For threaded marking/block reclaiming
594584static unsigned int sRunningThreads = 0 ;
@@ -615,20 +605,16 @@ static bool sgThreadPoolAbort = false;
615605
616606// Pthreads enters the sleep state while holding a mutex, so it no cost to update
617607// the sleeping state and thereby avoid over-signalling the condition
618- bool sThreadSleeping [MAX_GC_THREADS];
619- ThreadPoolSignal sThreadWake [MAX_GC_THREADS];
620- bool sThreadJobDoneSleeping = false ;
621- ThreadPoolSignal sThreadJobDone ;
608+ bool sThreadSleeping [MAX_GC_THREADS];
609+ std::condition_variable_any* sThreadWake [MAX_GC_THREADS];
610+ bool sThreadJobDoneSleeping = false ;
611+ std::condition_variable_any* sThreadJobDone ;
622612
623613
624- static inline void SignalThreadPool (ThreadPoolSignal & ioSignal, bool sThreadSleeping )
614+ static inline void SignalThreadPool (std::condition_variable_any* ioSignal, bool sThreadSleeping )
625615{
626- #ifdef HX_GC_PTHREADS
627- if (sThreadSleeping )
628- pthread_cond_signal (&ioSignal);
629- #else
630- ioSignal.Set ();
631- #endif
616+ if (sThreadSleeping )
617+ ioSignal->notify_one ();
632618}
633619
634620static void wakeThreadLocked (int inThreadId)
@@ -1556,7 +1542,7 @@ struct GlobalChunks
15561542
15571543 if (MAX_GC_THREADS>1 && sLazyThreads )
15581544 {
1559- ThreadPoolAutoLock l (sThreadPoolLock );
1545+ std::lock_guard<std::recursive_mutex> l (sThreadPoolLock );
15601546
15611547 #ifdef PROFILE_THREAD_USAGE
15621548 #define CHECK_THREAD_WAKE (tid ) \
@@ -1730,7 +1716,7 @@ struct GlobalChunks
17301716 return result;
17311717 }
17321718 }
1733- ThreadPoolAutoLock l (sThreadPoolLock );
1719+ std::lock_guard<std::recursive_mutex> l (sThreadPoolLock );
17341720 completeThreadLocked (inThreadId);
17351721 }
17361722 return result;
@@ -4441,7 +4427,7 @@ class GlobalAllocator
44414427 if (mZeroListQueue + mThreadJobId < mZeroList .size ())
44424428 {
44434429 // Wake zeroing thread
4444- ThreadPoolAutoLock l (sThreadPoolLock );
4430+ std::lock_guard<std::recursive_mutex> l (sThreadPoolLock );
44454431 if (!(sRunningThreads & 0x01 ))
44464432 {
44474433 #ifdef PROFILE_THREAD_USAGE
@@ -4456,7 +4442,7 @@ class GlobalAllocator
44564442
44574443 void finishThreadJob (int inId)
44584444 {
4459- ThreadPoolAutoLock l (sThreadPoolLock );
4445+ std::lock_guard<std::recursive_mutex> l (sThreadPoolLock );
44604446 if (sRunningThreads & (1 <<inId))
44614447 {
44624448 sRunningThreads &= ~(1 <<inId);
@@ -4474,22 +4460,15 @@ class GlobalAllocator
44744460
44754461 void waitForThreadWake (int inId)
44764462 {
4477- #ifdef HX_GC_PTHREADS
4478- {
4479- ThreadPoolAutoLock l (sThreadPoolLock );
4480- int count = 0 ;
4463+ std::lock_guard<std::recursive_mutex> l (sThreadPoolLock );
4464+ int count = 0 ;
44814465
4482- // May be woken multiple times if sRunningThreads is set to 0 then 1 before we sleep
4483- sThreadSleeping [inId] = true ;
4484- // Spurious wake?
4485- while ( !(sRunningThreads & (1 <<inId) ) )
4486- WaitThreadLocked (sThreadWake [inId]);
4487- sThreadSleeping [inId] = false ;
4488- }
4489- #else
4490- while ( !(sRunningThreads & (1 <<inId) ) )
4491- sThreadWake [inId].Wait ();
4492- #endif
4466+ // May be woken multiple times if sRunningThreads is set to 0 then 1 before we sleep
4467+ sThreadSleeping [inId] = true ;
4468+ // Spurious wake?
4469+ while ( !(sRunningThreads & (1 <<inId) ) )
4470+ WaitThreadLocked (sThreadWake [inId]);
4471+ sThreadSleeping [inId] = false ;
44934472 }
44944473
44954474
@@ -4552,19 +4531,18 @@ class GlobalAllocator
45524531 {
45534532 void *info = (void *)(size_t )inId;
45544533
4555- #ifdef HX_GC_PTHREADS
4556- pthread_cond_init (&sThreadWake [inId],0 );
4557- sThreadSleeping [inId] = false ;
4558- if (inId==0 )
4559- pthread_cond_init (&sThreadJobDone ,0 );
4560-
4561- pthread_t result = 0 ;
4562- int created = pthread_create (&result,0 ,SThreadLoop,info);
4563- bool ok = created==0 ;
4564- #elif defined(EMSCRIPTEN)
4534+ #if defined(EMSCRIPTEN)
45654535 // Only one thread
45664536 #else
4567- bool ok = HxCreateDetachedThread (SThreadLoop, info);
4537+ sThreadWake [inId] = new std::condition_variable_any ();
4538+ if (0 == inId)
4539+ {
4540+ sThreadJobDone = new std::condition_variable_any ();
4541+ }
4542+
4543+ sThreadSleeping [inId] = false ;
4544+
4545+ HxCreateDetachedThread (SThreadLoop, info);
45684546 #endif
45694547 }
45704548
@@ -4579,7 +4557,7 @@ class GlobalAllocator
45794557 sgThreadPoolAbort = true ;
45804558 if (sgThreadPoolJob==tpjAsyncZeroJit)
45814559 {
4582- ThreadPoolAutoLock l (sThreadPoolLock );
4560+ std::lock_guard<std::recursive_mutex> l (sThreadPoolLock );
45834561 // Thread will be waiting, but not finished
45844562 if (sRunningThreads & 0x1 )
45854563 {
@@ -4591,16 +4569,11 @@ class GlobalAllocator
45914569 }
45924570
45934571
4594- #ifdef HX_GC_PTHREADS
4595- ThreadPoolAutoLock lock (sThreadPoolLock );
4572+ std::lock_guard<std::recursive_mutex> l (sThreadPoolLock );
45964573 sThreadJobDoneSleeping = true ;
45974574 while (sRunningThreads )
45984575 WaitThreadLocked (sThreadJobDone );
45994576 sThreadJobDoneSleeping = false ;
4600- #else
4601- while (sRunningThreads )
4602- sThreadJobDone .Wait ();
4603- #endif
46044577 sgThreadPoolAbort = false ;
46054578 sAllThreads = 0 ;
46064579 sgThreadPoolJob = tpjNone;
@@ -4623,10 +4596,7 @@ class GlobalAllocator
46234596 CreateWorker (i);
46244597 }
46254598
4626- #ifdef HX_GC_PTHREADS
4627- ThreadPoolAutoLock lock (sThreadPoolLock );
4628- #endif
4629-
4599+ std::lock_guard<std::recursive_mutex> l (sThreadPoolLock );
46304600
46314601 sgThreadPoolJob = inJob;
46324602
@@ -4646,15 +4616,10 @@ class GlobalAllocator
46464616 if (inWait)
46474617 {
46484618 // Join the workers...
4649- #ifdef HX_GC_PTHREADS
46504619 sThreadJobDoneSleeping = true ;
46514620 while (sRunningThreads )
46524621 WaitThreadLocked (sThreadJobDone );
46534622 sThreadJobDoneSleeping = false ;
4654- #else
4655- while (sRunningThreads )
4656- sThreadJobDone .Wait ();
4657- #endif
46584623
46594624 sAllThreads = 0 ;
46604625 sgThreadPoolJob = tpjNone;
0 commit comments