[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