[x265] [PATCH] threading: add RWLock and RWScopedLock

Ximing Cheng chengximing1989 at foxmail.com
Sun Apr 3 14:05:02 CEST 2016


# HG changeset patch
# User Ximing Cheng <ximingcheng at tencent.com>
# Date 1459684811 -28800
#      Sun Apr 03 20:00:11 2016 +0800
# Node ID 1071a3c92f2be6fcf0e5178266a3382458690429
# Parent  601877ef465c549efe24063afa0479a39e369010
threading: add RWLock and RWScopedLock

diff -r 601877ef465c -r 1071a3c92f2b source/common/threading.h
--- a/source/common/threading.h	Sun Apr 03 16:29:59 2016 +0800
+++ b/source/common/threading.h	Sun Apr 03 20:00:11 2016 +0800
@@ -131,6 +131,41 @@
     CRITICAL_SECTION handle;
 };
 
+#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
+class RWLock
+{
+public:
+
+    RWLock()
+    {
+        InitializeSRWLock(&rwlock);
+    }
+
+    void acquireR()
+    {
+        AcquireSRWLockShared(&rwlock);
+    }
+
+    void acquireW()
+    {
+        AcquireSRWLockExclusive(&rwlock);
+    }
+
+    void releaseR()
+    {
+        ReleaseSRWLockShared(&rwlock);
+    }
+
+    void releaseW()
+    {
+        ReleaseSRWLockExclusive(&rwlock);
+    }
+
+protected:
+    SRWLOCK rwlock;
+};
+#endif
+
 class Event
 {
 public:
@@ -192,7 +227,7 @@
     ~ThreadSafeInteger()
     {
         /* SRW locks do not need to be explicitly destroyed */
-#if defined(_WIN32_WINNT) && _WIN32_WINNT < _WIN32_WINNT_VISTA
+#if _WIN32_WINNT < _WIN32_WINNT_VISTA
         DeleteCriticalSection(&m_cs);
 #endif
         XP_CONDITION_VAR_FREE(&m_cv);
@@ -332,6 +367,44 @@
     pthread_mutex_t handle;
 };
 
+class RWLock
+{
+public:
+
+    RWLock()
+    {
+        pthread_rwlock_init(&rwlock, NULL);
+    }
+
+    ~RWLock()
+    {
+        pthread_rwlock_destroy(&rwlock);
+    }
+
+    void acquireR()
+    {
+        pthread_rwlock_rdlock(&rwlock);
+    }
+
+    void acquireW()
+    {
+        pthread_rwlock_wrlock(&rwlock);
+    }
+
+    void releaseR()
+    {
+        pthread_rwlock_unlock(&rwlock);
+    }
+
+    void releaseW()
+    {
+        pthread_rwlock_unlock(&rwlock);
+    }
+
+protected:
+    pthread_rwlock_t rwlock;
+};
+
 class Event
 {
 public:
@@ -574,6 +647,28 @@
     Lock &inst;
 };
 
+#if !(defined(_WIN32_WINNT) && _WIN32_WINNT < _WIN32_WINNT_VISTA)
+class RWScopedLock
+{
+public:
+
+    RWScopedLock(RWLock &instance) : inst(instance)
+    {
+        this->inst.acquireW();
+    }
+
+    ~RWScopedLock()
+    {
+        this->inst.releaseW();
+    }
+
+protected:
+    RWScopedLock &operator =(const RWScopedLock &);
+
+    RWLock &inst;
+};
+#endif
+
 // Utility class which adds elapsed time of the scope of the object into the
 // accumulator provided to the constructor
 struct ScopedElapsedTime
diff -r 601877ef465c -r 1071a3c92f2b source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp	Sun Apr 03 16:29:59 2016 +0800
+++ b/source/encoder/frameencoder.cpp	Sun Apr 03 20:00:11 2016 +0800
@@ -895,7 +895,11 @@
     tld.analysis.m_param = m_param;
     if (m_param->bEnableWavefront)
     {
+#if defined(_WIN32_WINNT) && _WIN32_WINNT < _WIN32_WINNT_VISTA
         ScopedLock self(curRow.lock);
+#else
+        RWScopedLock self(curRow.lock);
+#endif
         if (!curRow.active)
             /* VBV restart is in progress, exit out */
             return;
@@ -1131,7 +1135,7 @@
                         if (r != row)
                         {
                             /* if row was active (ready to be run) clear active bit and bitmap bit for this row */
-                            stopRow.lock.acquire();
+                            stopRow.lock.acquireW();
                             while (stopRow.active)
                             {
                                 if (dequeueRow(r * 2))
@@ -1139,19 +1143,19 @@
                                 else
                                 {
                                     /* we must release the row lock to allow the thread to exit */
-                                    stopRow.lock.release();
+                                    stopRow.lock.releaseW();
                                     GIVE_UP_TIME();
-                                    stopRow.lock.acquire();
+                                    stopRow.lock.acquireW();
                                 }
                             }
-                            stopRow.lock.release();
+                            stopRow.lock.releaseW();
 
                             bool bRowBusy = true;
                             do
                             {
-                                stopRow.lock.acquire();
+                                stopRow.lock.acquireR();
                                 bRowBusy = stopRow.busy;
-                                stopRow.lock.release();
+                                stopRow.lock.releaseR();
 
                                 if (bRowBusy)
                                 {
@@ -1181,7 +1185,11 @@
             (!m_bAllRowsStop || intRow + 1 < m_vbvResetTriggerRow))
         {
             /* activate next row */
+#if defined(_WIN32_WINNT) && _WIN32_WINNT < _WIN32_WINNT_VISTA
             ScopedLock below(m_rows[row + 1].lock);
+#else
+            RWScopedLock below(m_rows[row + 1].lock);
+#endif
             if (m_rows[row + 1].active == false &&
                 m_rows[row + 1].completed + 2 <= curRow.completed)
             {
@@ -1191,7 +1199,11 @@
             }
         }
 
+#if defined(_WIN32_WINNT) && _WIN32_WINNT < _WIN32_WINNT_VISTA
         ScopedLock self(curRow.lock);
+#else
+        RWScopedLock self(curRow.lock);
+#endif
         if ((m_bAllRowsStop && intRow > m_vbvResetTriggerRow) ||
             (row > 0 && ((curRow.completed < numCols - 1) || (m_rows[row - 1].completed < numCols)) && m_rows[row - 1].completed < m_rows[row].completed + 2))
         {
diff -r 601877ef465c -r 1071a3c92f2b source/encoder/frameencoder.h
--- a/source/encoder/frameencoder.h	Sun Apr 03 16:29:59 2016 +0800
+++ b/source/encoder/frameencoder.h	Sun Apr 03 20:00:11 2016 +0800
@@ -79,7 +79,11 @@
     /* Threading variables */
 
     /* This lock must be acquired when reading or writing m_active or m_busy */
+#if defined(_WIN32_WINNT) && _WIN32_WINNT < _WIN32_WINNT_VISTA
     Lock              lock;
+#else
+    RWLock            lock;
+#endif
 
     /* row is ready to run, has no neighbor dependencies. The row may have
      * external dependencies (reference frame pixels) that prevent it from being




More information about the x265-devel mailing list