From 54d58e1502ab6b53645da7e67f1fff879206d805 Mon Sep 17 00:00:00 2001 From: Hugh Sanderson Date: Tue, 30 Jul 2024 19:54:14 +0800 Subject: [PATCH] Allocate pthread structures using 'new' to avoid copying and respect alignment. For https://github.com/HaxeFoundation/hxcpp/issues/1136 --- include/hx/Thread.h | 40 ++++++++++++++++++++++++---------------- src/hx/Thread.cpp | 32 ++++++++++++++++++-------------- src/hx/gc/Immix.cpp | 2 +- 3 files changed, 43 insertions(+), 31 deletions(-) diff --git a/include/hx/Thread.h b/include/hx/Thread.h index b2c3bbfb4..069d51e87 100644 --- a/include/hx/Thread.h +++ b/include/hx/Thread.h @@ -91,22 +91,28 @@ struct HxMutex pthread_mutexattr_t mta; pthread_mutexattr_init(&mta); pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE); - mValid = pthread_mutex_init(&mMutex,&mta) ==0; + mMutex = new pthread_mutex_t(); + mValid = pthread_mutex_init(mMutex,&mta) ==0; } - ~HxMutex() { if (mValid) pthread_mutex_destroy(&mMutex); } - void Lock() { pthread_mutex_lock(&mMutex); } - void Unlock() { pthread_mutex_unlock(&mMutex); } - bool TryLock() { return !pthread_mutex_trylock(&mMutex); } + ~HxMutex() + { + if (mValid) + pthread_mutex_destroy(mMutex); + delete mMutex; + } + void Lock() { pthread_mutex_lock(mMutex); } + void Unlock() { pthread_mutex_unlock(mMutex); } + bool TryLock() { return !pthread_mutex_trylock(mMutex); } bool IsValid() { return mValid; } void Clean() { if (mValid) - pthread_mutex_destroy(&mMutex); + pthread_mutex_destroy(mMutex); mValid = 0; } bool mValid; - pthread_mutex_t mMutex; + pthread_mutex_t *mMutex; }; #define THREAD_FUNC_TYPE void * @@ -196,13 +202,14 @@ struct HxSemaphore { mSet = false; mValid = true; - pthread_cond_init(&mCondition,0); + mCondition = new pthread_cond_t(); + pthread_cond_init(mCondition,0); } ~HxSemaphore() { if (mValid) { - pthread_cond_destroy(&mCondition); + pthread_cond_destroy(mCondition); } } // For autolock @@ -213,13 +220,13 @@ struct HxSemaphore if (!mSet) { mSet = true; - pthread_cond_signal( &mCondition ); + pthread_cond_signal( mCondition ); } } void QSet() { mSet = true; - pthread_cond_signal( &mCondition ); + pthread_cond_signal( mCondition ); } void Reset() { @@ -231,14 +238,14 @@ struct HxSemaphore { AutoLock lock(mMutex); while( !mSet ) - pthread_cond_wait( &mCondition, &mMutex.mMutex ); + pthread_cond_wait( mCondition, mMutex.mMutex ); mSet = false; } // when we already hold the mMutex lock ... void QWait() { while( !mSet ) - pthread_cond_wait( &mCondition, &mMutex.mMutex ); + pthread_cond_wait( mCondition, mMutex.mMutex ); mSet = false; } // Returns true if the wait was success, false on timeout. @@ -262,7 +269,7 @@ struct HxSemaphore int result = 0; // Wait for set to be true... - while( !mSet && (result=pthread_cond_timedwait( &mCondition, &mMutex.mMutex, &spec )) != ETIMEDOUT) + while( !mSet && (result=pthread_cond_timedwait( mCondition, mMutex.mMutex, &spec )) != ETIMEDOUT) { if (result!=0) { @@ -290,13 +297,14 @@ struct HxSemaphore if (mValid) { mValid = false; - pthread_cond_destroy(&mCondition); + pthread_cond_destroy(mCondition); } + delete mCondition; } HxMutex mMutex; - pthread_cond_t mCondition; + pthread_cond_t *mCondition; bool mSet; bool mValid; }; diff --git a/src/hx/Thread.cpp b/src/hx/Thread.cpp index 0dedb89d9..733933b1f 100644 --- a/src/hx/Thread.cpp +++ b/src/hx/Thread.cpp @@ -628,8 +628,8 @@ class hxCondition : public hx::Object { CONDITION_VARIABLE cond; #endif #else - pthread_cond_t cond; - pthread_mutex_t mutex; + pthread_cond_t *cond; + pthread_mutex_t *mutex; #endif hx::InternalFinalizer *mFinalizer; hxCondition() { @@ -645,11 +645,13 @@ class hxCondition : public hx::Object { #else pthread_condattr_t cond_attr; pthread_condattr_init(&cond_attr); - pthread_cond_init(&cond, &cond_attr); + cond = new pthread_cond_t(); + pthread_cond_init(cond, &cond_attr); pthread_condattr_destroy(&cond_attr); pthread_mutexattr_t mutex_attr; pthread_mutexattr_init(&mutex_attr); - pthread_mutex_init(&mutex, &mutex_attr); + mutex = new pthread_mutex_t(); + pthread_mutex_init(mutex, &mutex_attr); pthread_mutexattr_destroy(&mutex_attr); #endif } @@ -667,8 +669,10 @@ class hxCondition : public hx::Object { DeleteCriticalSection(&cond->cs); #endif #else - pthread_cond_destroy(&cond->cond); - pthread_mutex_destroy(&cond->mutex); + pthread_cond_destroy(cond->cond); + delete cond->cond; + pthread_mutex_destroy(cond->mutex); + delete cond->mutex; #endif } } @@ -679,7 +683,7 @@ class hxCondition : public hx::Object { EnterCriticalSection(&cs); #endif #else - pthread_mutex_lock(&mutex); + pthread_mutex_lock(mutex); #endif } @@ -691,7 +695,7 @@ class hxCondition : public hx::Object { return false; #endif #else - return pthread_mutex_trylock(&mutex); + return pthread_mutex_trylock(mutex); #endif } @@ -701,17 +705,17 @@ class hxCondition : public hx::Object { LeaveCriticalSection(&cs); #endif #else - pthread_mutex_unlock(&mutex); + pthread_mutex_unlock(mutex); #endif } void Wait() { #ifdef HX_WINDOWS #ifndef HXCPP_WINXP_COMPAT - SleepConditionVariableCS(&cond,&cs,INFINITE); + SleepConditionVariableCS(cond,&cs,INFINITE); #endif #else - pthread_cond_wait(&cond, &mutex); + pthread_cond_wait(cond, mutex); #endif } @@ -735,7 +739,7 @@ class hxCondition : public hx::Object { delta -= idelta2 * 1e9; t.tv_sec = tv.tv_sec + idelta + idelta2; t.tv_nsec = (long)delta; - return pthread_cond_timedwait(&cond, &mutex, &t); + return pthread_cond_timedwait(cond, mutex, &t); #endif } void Signal() { @@ -744,7 +748,7 @@ class hxCondition : public hx::Object { WakeConditionVariable(&cond); #endif #else - pthread_cond_signal(&cond); + pthread_cond_signal(cond); #endif } void Broadcast() { @@ -753,7 +757,7 @@ class hxCondition : public hx::Object { WakeAllConditionVariable(&cond); #endif #else - pthread_cond_broadcast(&cond); + pthread_cond_broadcast(cond); #endif } }; diff --git a/src/hx/gc/Immix.cpp b/src/hx/gc/Immix.cpp index 4894f79e3..00d2f2ff5 100644 --- a/src/hx/gc/Immix.cpp +++ b/src/hx/gc/Immix.cpp @@ -580,7 +580,7 @@ static ThreadPoolLock sThreadPoolLock; typedef pthread_cond_t ThreadPoolSignal; inline void WaitThreadLocked(ThreadPoolSignal &ioSignal) { - pthread_cond_wait(&ioSignal, &sThreadPoolLock.mMutex); + pthread_cond_wait(&ioSignal, sThreadPoolLock.mMutex); } #else typedef HxSemaphore ThreadPoolSignal;