[x265] [PATCH] ThreadSafeInteger: change default lock into read write lock

Ximing Cheng chengximing1989 at foxmail.com
Sun Apr 3 09:59:35 CEST 2016


# HG changeset patch
# User Ximing Cheng <ximingcheng at tencent.com>
# Date 1459670195 -28800
#      Sun Apr 03 15:56:35 2016 +0800
# Node ID 4260ba22dac98d2b097fc6a03023e5ba578652fb
# Parent  5b01678f6fb4e89e23cd41295592a9aa5d51d4ba
ThreadSafeInteger: change default lock into read write lock

diff -r 5b01678f6fb4 -r 4260ba22dac9 source/common/frame.cpp
--- a/source/common/frame.cpp	Sat Apr 02 19:08:49 2016 +0100
+++ b/source/common/frame.cpp	Sun Apr 03 15:56:35 2016 +0800
@@ -30,6 +30,7 @@
 
 Frame::Frame()
 {
+    m_reconRowCount.init();
     m_bChromaExtended = false;
     m_lowresInit = false;
     m_reconRowCount.set(0);
@@ -55,6 +56,8 @@
         X265_CHECK((m_reconColCount == NULL), "m_reconColCount was initialized");
         m_numRows = (m_fencPic->m_picHeight + g_maxCUSize - 1)  / g_maxCUSize;
         m_reconColCount = new ThreadSafeInteger[m_numRows];
+        for (int i = 0; i < m_numRows; i++)
+            m_reconColCount[i].init(true);
 
         if (quantOffsets)
         {
diff -r 5b01678f6fb4 -r 4260ba22dac9 source/common/threading.h
--- a/source/common/threading.h	Sat Apr 02 19:08:49 2016 +0100
+++ b/source/common/threading.h	Sun Apr 03 15:56:35 2016 +0800
@@ -174,73 +174,126 @@
 class ThreadSafeInteger
 {
 public:
-
-    ThreadSafeInteger()
+    /* useReadWriteLock is useless, just be compatible with pthread version */
+    void init(bool useReadWriteLock = true)
     {
+        /* disable MSVC warnnings */
+        (void)useReadWriteLock;
         m_val = 0;
+        InitializeConditionVariable(&m_cv);
+        /* Slim Reader/Writer (SRW) Locks minimum supported in Windows Vista */
+#if _WIN32_WINNT < _WIN32_WINNT_VISTA
         InitializeCriticalSection(&m_cs);
-        InitializeConditionVariable(&m_cv);
+#else
+        InitializeSRWLock(&m_rwlock);
+#endif
     }
 
     ~ThreadSafeInteger()
     {
+        /* SRW locks do not need to be explicitly destroyed */
+#if defined(_WIN32_WINNT) && _WIN32_WINNT < _WIN32_WINNT_VISTA
         DeleteCriticalSection(&m_cs);
+#endif
         XP_CONDITION_VAR_FREE(&m_cv);
     }
 
     int waitForChange(int prev)
     {
+#if _WIN32_WINNT < _WIN32_WINNT_VISTA
         EnterCriticalSection(&m_cs);
-        if (m_val == prev)
+        while (m_val == prev)
             SleepConditionVariableCS(&m_cv, &m_cs, INFINITE);
         LeaveCriticalSection(&m_cs);
+#else
+        AcquireSRWLockShared(&m_rwlock);
+        while (m_val == prev)
+            SleepConditionVariableSRW(&m_cv, &m_rwlock, INFINITE, CONDITION_VARIABLE_LOCKMODE_SHARED);
+        ReleaseSRWLockShared(&m_rwlock);
+#endif
         return m_val;
     }
 
     int get()
     {
+#if _WIN32_WINNT < _WIN32_WINNT_VISTA
         EnterCriticalSection(&m_cs);
         int ret = m_val;
         LeaveCriticalSection(&m_cs);
+#else
+        AcquireSRWLockShared(&m_rwlock);
+        int ret = m_val;
+        ReleaseSRWLockShared(&m_rwlock);
+#endif
         return ret;
     }
 
     int getIncr(int n = 1)
     {
+#if _WIN32_WINNT < _WIN32_WINNT_VISTA
         EnterCriticalSection(&m_cs);
         int ret = m_val;
         m_val += n;
         LeaveCriticalSection(&m_cs);
+#else
+        AcquireSRWLockExclusive(&m_rwlock);
+        int ret = m_val;
+        m_val += n;
+        ReleaseSRWLockExclusive(&m_rwlock);
+#endif
         return ret;
     }
 
     void set(int newval)
     {
+#if _WIN32_WINNT < _WIN32_WINNT_VISTA
         EnterCriticalSection(&m_cs);
         m_val = newval;
         WakeAllConditionVariable(&m_cv);
         LeaveCriticalSection(&m_cs);
+#else
+        AcquireSRWLockExclusive(&m_rwlock);
+        m_val = newval;
+        WakeAllConditionVariable(&m_cv);
+        ReleaseSRWLockExclusive(&m_rwlock);
+#endif
     }
 
     void poke(void)
     {
         /* awaken all waiting threads, but make no change */
+#if _WIN32_WINNT < _WIN32_WINNT_VISTA
         EnterCriticalSection(&m_cs);
         WakeAllConditionVariable(&m_cv);
         LeaveCriticalSection(&m_cs);
+#else
+        AcquireSRWLockExclusive(&m_rwlock);
+        WakeAllConditionVariable(&m_cv);
+        ReleaseSRWLockExclusive(&m_rwlock);
+#endif
     }
 
     void incr()
     {
+#if _WIN32_WINNT < _WIN32_WINNT_VISTA
         EnterCriticalSection(&m_cs);
         m_val++;
         WakeAllConditionVariable(&m_cv);
         LeaveCriticalSection(&m_cs);
+#else
+        AcquireSRWLockExclusive(&m_rwlock);
+        m_val++;
+        WakeAllConditionVariable(&m_cv);
+        ReleaseSRWLockExclusive(&m_rwlock);
+#endif
     }
 
 protected:
 
     CRITICAL_SECTION   m_cs;
+#if defined(_WIN32_WINNT) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
+    SRWLOCK            m_rwlock;
+#endif
     CONDITION_VARIABLE m_cv;
     int                m_val;
 };
@@ -369,27 +422,38 @@
 class ThreadSafeInteger
 {
 public:
-
-    ThreadSafeInteger()
+    /* pthread_cond_wait only accept mutex param */
+    void init(bool useReadWriteLock = false)
     {
+        m_useReadWriteLock = useReadWriteLock;
         m_val = 0;
-        if (pthread_mutex_init(&m_mutex, NULL) ||
-            pthread_cond_init(&m_cond, NULL))
+        if (!m_useReadWriteLock && (pthread_mutex_init(&m_mutex, NULL) ||
+            pthread_cond_init(&m_cond, NULL)))
         {
             x265_log(NULL, X265_LOG_ERROR, "fatal: unable to initialize conditional variable\n");
         }
+        else if (m_useReadWriteLock && pthread_rwlock_init(&m_rwlock, NULL))
+        {
+            x265_log(NULL, X265_LOG_ERROR, "fatal: unable to initialize read write lock\n");
+        }
     }
 
     ~ThreadSafeInteger()
     {
-        pthread_cond_destroy(&m_cond);
-        pthread_mutex_destroy(&m_mutex);
+        if (!m_useReadWriteLock)
+        {
+            pthread_cond_destroy(&m_cond);
+            pthread_mutex_destroy(&m_mutex);
+        }
+        else
+            pthread_rwlock_destroy(&m_rwlock);
     }
 
     int waitForChange(int prev)
     {
+        X265_CHECK(!m_useReadWriteLock, "ThreadSafeInteger with waitForChange should disable read write lock!\n");
         pthread_mutex_lock(&m_mutex);
-        if (m_val == prev)
+        while (m_val == prev)
             pthread_cond_wait(&m_cond, &m_mutex);
         pthread_mutex_unlock(&m_mutex);
         return m_val;
@@ -397,31 +461,62 @@
 
     int get()
     {
-        pthread_mutex_lock(&m_mutex);
-        int ret = m_val;
-        pthread_mutex_unlock(&m_mutex);
+        int ret;
+        if (!m_useReadWriteLock)
+        {
+            pthread_mutex_lock(&m_mutex);
+            ret = m_val;
+            pthread_mutex_unlock(&m_mutex);
+        }
+        else
+        {
+            pthread_rwlock_rdlock(&m_rwlock);
+            ret = m_val;
+            pthread_rwlock_unlock(&m_rwlock);
+        }
         return ret;
     }
 
     int getIncr(int n = 1)
     {
-        pthread_mutex_lock(&m_mutex);
-        int ret = m_val;
-        m_val += n;
-        pthread_mutex_unlock(&m_mutex);
+        int ret;
+        if (!m_useReadWriteLock)
+        {
+            pthread_mutex_lock(&m_mutex);
+            ret = m_val;
+            m_val += n;
+            pthread_mutex_unlock(&m_mutex);
+        }
+        else
+        {
+            pthread_rwlock_wrlock(&m_rwlock);
+            ret = m_val;
+            m_val += n;
+            pthread_rwlock_unlock(&m_rwlock);
+        }
         return ret;
     }
 
     void set(int newval)
     {
-        pthread_mutex_lock(&m_mutex);
-        m_val = newval;
-        pthread_cond_broadcast(&m_cond);
-        pthread_mutex_unlock(&m_mutex);
+        if (!m_useReadWriteLock)
+        {
+            pthread_mutex_lock(&m_mutex);
+            m_val = newval;
+            pthread_cond_broadcast(&m_cond);
+            pthread_mutex_unlock(&m_mutex);
+        }
+        else
+        {
+            pthread_rwlock_wrlock(&m_rwlock);
+            m_val = newval;
+            pthread_rwlock_unlock(&m_rwlock);
+        }
     }
 
     void poke(void)
     {
+        X265_CHECK(!m_useReadWriteLock, "ThreadSafeInteger with poke should disable read write lock!\n");
         /* awaken all waiting threads, but make no change */
         pthread_mutex_lock(&m_mutex);
         pthread_cond_broadcast(&m_cond);
@@ -430,17 +525,28 @@
 
     void incr()
     {
-        pthread_mutex_lock(&m_mutex);
-        m_val++;
-        pthread_cond_broadcast(&m_cond);
-        pthread_mutex_unlock(&m_mutex);
+        if (!m_useReadWriteLock)
+        {
+            pthread_mutex_lock(&m_mutex);
+            m_val++;
+            pthread_cond_broadcast(&m_cond);
+            pthread_mutex_unlock(&m_mutex);
+        }
+        else
+        {
+            pthread_rwlock_wrlock(&m_rwlock);
+            m_val++;
+            pthread_rwlock_unlock(&m_rwlock);
+        }
     }
 
 protected:
 
-    pthread_mutex_t m_mutex;
-    pthread_cond_t  m_cond;
-    int             m_val;
+    pthread_mutex_t  m_mutex;
+    pthread_rwlock_t m_rwlock;
+    pthread_cond_t   m_cond;
+    int              m_val;
+    bool             m_useReadWriteLock;
 };
 
 #endif // ifdef _WIN32
diff -r 5b01678f6fb4 -r 4260ba22dac9 source/common/threadpool.h
--- a/source/common/threadpool.h	Sat Apr 02 19:08:49 2016 +0100
+++ b/source/common/threadpool.h	Sun Apr 03 15:56:35 2016 +0800
@@ -129,7 +129,7 @@
     int               m_jobTotal;
     int               m_jobAcquired;
 
-    BondedTaskGroup()  { m_bondedPeerCount = m_jobTotal = m_jobAcquired = 0; }
+    BondedTaskGroup()  { m_bondedPeerCount = m_jobTotal = m_jobAcquired = 0; m_exitedPeerCount.init(); }
 
     /* Do not allow the instance to be destroyed before all bonded peers have
      * exited processTasks() */
diff -r 5b01678f6fb4 -r 4260ba22dac9 source/encoder/framefilter.h
--- a/source/encoder/framefilter.h	Sat Apr 02 19:08:49 2016 +0100
+++ b/source/encoder/framefilter.h	Sun Apr 03 15:56:35 2016 +0800
@@ -82,6 +82,9 @@
             , m_encData(NULL)
             , m_prevRow(NULL)
         {
+            m_lastCol.init(true);
+            m_allowedCol.init(true);
+            m_lastDeblocked.init(true);
         }
 
         ~ParallelFilter()
diff -r 5b01678f6fb4 -r 4260ba22dac9 source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp	Sat Apr 02 19:08:49 2016 +0100
+++ b/source/encoder/ratecontrol.cpp	Sun Apr 03 15:56:35 2016 +0800
@@ -166,6 +166,7 @@
 
 RateControl::RateControl(x265_param& p)
 {
+    m_startEndOrder.init();
     m_param = &p;
     int lowresCuWidth = ((m_param->sourceWidth / 2) + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;
     int lowresCuHeight = ((m_param->sourceHeight / 2) + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;
diff -r 5b01678f6fb4 -r 4260ba22dac9 source/input/y4m.cpp
--- a/source/input/y4m.cpp	Sat Apr 02 19:08:49 2016 +0100
+++ b/source/input/y4m.cpp	Sun Apr 03 15:56:35 2016 +0800
@@ -43,6 +43,8 @@
 
 Y4MInput::Y4MInput(InputFileInfo& info)
 {
+    readCount.init();
+    writeCount.init();
     for (int i = 0; i < QUEUE_SIZE; i++)
         buf[i] = NULL;
 
diff -r 5b01678f6fb4 -r 4260ba22dac9 source/input/yuv.cpp
--- a/source/input/yuv.cpp	Sat Apr 02 19:08:49 2016 +0100
+++ b/source/input/yuv.cpp	Sun Apr 03 15:56:35 2016 +0800
@@ -41,6 +41,8 @@
 
 YUVInput::YUVInput(InputFileInfo& info)
 {
+    readCount.init();
+    writeCount.init();
     for (int i = 0; i < QUEUE_SIZE; i++)
         buf[i] = NULL;
 
diff -r 5b01678f6fb4 -r 4260ba22dac9 source/output/reconplay.cpp
--- a/source/output/reconplay.cpp	Sat Apr 02 19:08:49 2016 +0100
+++ b/source/output/reconplay.cpp	Sun Apr 03 15:56:35 2016 +0800
@@ -54,7 +54,8 @@
     if (signal(SIGPIPE, sigpipe_handler) == SIG_ERR)
         general_log(&param, "exec", X265_LOG_ERROR, "Unable to register SIGPIPE handler: %s\n", strerror(errno));
 #endif
-
+    readCount.init();
+    writeCount.init();
     width = param.sourceWidth;
     height = param.sourceHeight;
     colorSpace = param.internalCsp;




More information about the x265-devel mailing list