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;

Reply via email to