Skip to content

Commit 4c6d59b

Browse files
author
Aidan Lee
committed
pointers to condition variables
1 parent 21ac9fa commit 4c6d59b

1 file changed

Lines changed: 36 additions & 71 deletions

File tree

src/hx/gc/Immix.cpp

Lines changed: 36 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
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;
572573
typedef 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
594584
static 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

634620
static 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

Comments
 (0)