sal/osl/unx/conditn.cxx | 169 +++++++----------------------------------------- 1 file changed, 25 insertions(+), 144 deletions(-)
New commits: commit 65efe0e2783660780da7dc126e5f34422f312814 Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Tue Feb 14 10:48:56 2023 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Thu Feb 16 09:00:51 2023 +0000 use std::condition_variable for oslCondition which is both faster (because we don't need to allocate a pthread condition) and simpler Change-Id: I0a98432b5106c1c2b8e8ed97cbd779ef2b0c9e4d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146996 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/sal/osl/unx/conditn.cxx b/sal/osl/unx/conditn.cxx index 602240922b8c..16c4ad11b15f 100644 --- a/sal/osl/unx/conditn.cxx +++ b/sal/osl/unx/conditn.cxx @@ -20,9 +20,9 @@ #include <sal/config.h> #include <assert.h> +#include <condition_variable> +#include <mutex> -#include "system.hxx" -#include "unixerrnostring.hxx" #include <sal/log.hxx> #include <sal/types.h> @@ -33,48 +33,16 @@ namespace { struct oslConditionImpl { - pthread_cond_t m_Condition; - pthread_mutex_t m_Lock; - bool m_State; + std::condition_variable m_Condition; + std::mutex m_Lock; + bool m_State = false; }; } oslCondition SAL_CALL osl_createCondition() { - oslConditionImpl* pCond; - int nRet=0; - - pCond = static_cast<oslConditionImpl*>(malloc(sizeof(oslConditionImpl))); - - if ( pCond == nullptr ) - { - return nullptr; - } - - pCond->m_State = false; - - /* init condition variable with default attr. (PTHREAD_PROCESS_PRIVAT) */ - nRet = pthread_cond_init(&pCond->m_Condition, PTHREAD_CONDATTR_DEFAULT); - if ( nRet != 0 ) - { - SAL_WARN( "sal.osl.condition", "pthread_cond_init failed: " << UnixErrnoString(nRet) ); - - free(pCond); - return nullptr; - } - - nRet = pthread_mutex_init(&pCond->m_Lock, PTHREAD_MUTEXATTR_DEFAULT); - if ( nRet != 0 ) - { - SAL_WARN( "sal.osl.condition", "pthread_mutex_init failed: " << UnixErrnoString(nRet) ); - - nRet = pthread_cond_destroy(&pCond->m_Condition); - SAL_WARN_IF( nRet != 0, "sal.osl.condition", "pthread_cond_destroy failed: " << UnixErrnoString(nRet) ); - - free(pCond); - pCond = nullptr; - } + oslConditionImpl* pCond = new oslConditionImpl; SAL_INFO( "sal.osl.condition", "osl_createCondition(): " << pCond ); @@ -90,48 +58,22 @@ void SAL_CALL osl_destroyCondition(oslCondition Condition) SAL_INFO( "sal.osl.condition", "osl_destroyCondition(" << pCond << ")" ); if ( pCond ) - { - int nRet = pthread_cond_destroy(&pCond->m_Condition); - SAL_WARN_IF( nRet != 0, "sal.osl.condition", "pthread_cond_destroy failed: " << UnixErrnoString(nRet) ); - nRet = pthread_mutex_destroy(&pCond->m_Lock); - SAL_WARN_IF( nRet != 0, "sal.osl.condition", "pthread_mutex_destroy failed: " << UnixErrnoString(nRet) ); - - free(Condition); - } + delete pCond; } sal_Bool SAL_CALL osl_setCondition(oslCondition Condition) { oslConditionImpl* pCond; - int nRet=0; assert(Condition); pCond = static_cast<oslConditionImpl*>(Condition); - nRet = pthread_mutex_lock(&pCond->m_Lock); - if ( nRet != 0 ) { - SAL_WARN( "sal.osl.condition", "osl_setCondition(" << pCond << "): pthread_mutex_lock failed: " << UnixErrnoString(nRet) ); - return false; - } - - pCond->m_State = true; - nRet = pthread_cond_broadcast(&pCond->m_Condition); - if ( nRet != 0 ) - { - SAL_WARN( "sal.osl.condition", "osl_setCondition(" << pCond << "): pthread_cond_broadcast failed: " << UnixErrnoString(nRet) ); - // try to unlock the mutex - pthread_mutex_unlock(&pCond->m_Lock); - return false; - } + std::unique_lock g(pCond->m_Lock); - nRet = pthread_mutex_unlock(&pCond->m_Lock); - if ( nRet != 0 ) - { - SAL_WARN( "sal.osl.condition", "osl_setCondition(" << pCond << "): pthread_mutex_unlock failed: " << UnixErrnoString(nRet) ); - return false; + pCond->m_State = true; + pCond->m_Condition.notify_all(); } - SAL_INFO( "sal.osl.condition", "osl_setCondition(" << pCond << ")" ); return true; @@ -141,28 +83,16 @@ sal_Bool SAL_CALL osl_setCondition(oslCondition Condition) sal_Bool SAL_CALL osl_resetCondition(oslCondition Condition) { oslConditionImpl* pCond; - int nRet=0; assert(Condition); pCond = static_cast<oslConditionImpl*>(Condition); - nRet = pthread_mutex_lock(&pCond->m_Lock); - if ( nRet != 0 ) { - SAL_WARN( "sal.osl.condition", "osl_resetCondition(" << pCond << "): pthread_mutex_lock failed: " << UnixErrnoString(nRet) ); - return false; - } + std::unique_lock g(pCond->m_Lock); - pCond->m_State = false; - - nRet = pthread_mutex_unlock(&pCond->m_Lock); - if ( nRet != 0 ) - { - SAL_WARN( "sal.osl.condition", "osl_resetCondition(" << pCond << "): pthread_mutex_unlock failed: " << UnixErrnoString(nRet) ); - return false; + pCond->m_State = false; } - SAL_INFO( "sal.osl.condition", "osl_resetCondition(" << pCond << ")" ); return true; @@ -171,75 +101,30 @@ sal_Bool SAL_CALL osl_resetCondition(oslCondition Condition) oslConditionResult SAL_CALL osl_waitCondition(oslCondition Condition, const TimeValue* pTimeout) { oslConditionImpl* pCond; - int nRet=0; assert(Condition); pCond = static_cast<oslConditionImpl*>(Condition); SAL_INFO( "sal.osl.condition", "osl_waitCondition(" << pCond << ")" ); - nRet = pthread_mutex_lock(&pCond->m_Lock); - if ( nRet != 0 ) { - SAL_WARN( "sal.osl.condition", "osl_waitCondition(" << pCond << "): pthread_mutex_lock failed: " << UnixErrnoString(nRet) ); - return osl_cond_result_error; - } + std::unique_lock g(pCond->m_Lock); - if ( pTimeout ) - { - if ( ! pCond->m_State ) + if ( pTimeout ) { - struct timeval tp; - struct timespec to; - - gettimeofday(&tp, nullptr); - - SET_TIMESPEC( to, tp.tv_sec + pTimeout->Seconds, - tp.tv_usec * 1000 + pTimeout->Nanosec ); - - /* spurious wake up prevention */ - do + if ( ! pCond->m_State ) { - const int ret = pthread_cond_timedwait(&pCond->m_Condition, &pCond->m_Lock, &to); - if ( ret != 0 ) - { - if ( ret == ETIME || ret == ETIMEDOUT ) - { - nRet = pthread_mutex_unlock(&pCond->m_Lock); - SAL_WARN_IF( nRet != 0, "sal.osl.condition", "osl_waitCondition(" << pCond << "): pthread_mutex_unlock failed: " << UnixErrnoString(nRet) ); - - return osl_cond_result_timeout; - } - if ( ret != EINTR ) - { - nRet = pthread_mutex_unlock(&pCond->m_Lock); - SAL_WARN_IF( nRet != 0, "sal.osl.condition", "osl_waitCondition(" << pCond << "): pthread_mutex_unlock failed: " << UnixErrnoString(nRet) ); - return osl_cond_result_error; - } - } + auto duration = std::chrono::seconds(pTimeout->Seconds) + + std::chrono::nanoseconds(pTimeout->Nanosec); + if (!pCond->m_Condition.wait_for(g, duration, [&pCond](){return pCond->m_State;})) + return osl_cond_result_timeout; } - while ( !pCond->m_State ); } - } - else - { - while ( !pCond->m_State ) + else { - nRet = pthread_cond_wait(&pCond->m_Condition, &pCond->m_Lock); - if ( nRet != 0 ) - { - SAL_WARN( "sal.osl.condition", "osl_waitCondition(" << pCond << "): pthread_cond_wait failed: " << UnixErrnoString(nRet) ); - nRet = pthread_mutex_unlock(&pCond->m_Lock); - SAL_WARN_IF( nRet != 0, "sal.osl.condition", "osl_waitCondition(" << pCond << "): pthread_mutex_unlock failed: " << UnixErrnoString(nRet) ); - - return osl_cond_result_error; - } + pCond->m_Condition.wait(g, [&pCond](){return pCond->m_State;}); } } - - nRet = pthread_mutex_unlock(&pCond->m_Lock); - SAL_WARN_IF( nRet != 0, "sal.osl.condition", "osl_waitCondition(" << pCond << "): pthread_mutex_unlock failed: " << UnixErrnoString(nRet) ); - SAL_INFO( "sal.osl.condition", "osl_waitCondition(" << pCond << "): OK" ); return osl_cond_result_ok; @@ -249,19 +134,15 @@ sal_Bool SAL_CALL osl_checkCondition(oslCondition Condition) { bool State; oslConditionImpl* pCond; - int nRet=0; assert(Condition); pCond = static_cast<oslConditionImpl*>(Condition); - nRet = pthread_mutex_lock(&pCond->m_Lock); - SAL_WARN_IF( nRet != 0, "sal.osl.condition", "osl_checkCondition(" << pCond << "): pthread_mutex_lock failed: " << UnixErrnoString(nRet) ); - - State = pCond->m_State; - - nRet = pthread_mutex_unlock(&pCond->m_Lock); - SAL_WARN_IF( nRet != 0, "sal.osl.condition", "osl_checkCondition(" << pCond << "): pthread_mutex_unlock failed: " << UnixErrnoString(nRet) ); + { + std::unique_lock g(pCond->m_Lock); + State = pCond->m_State; + } SAL_INFO( "sal.osl.condition", "osl_checkCondition(" << pCond << "): " << (State ? "YES" : "NO") ); return State;