ref: bc566f0923d099531a573220ae7e83056f52da52
parent: eb00d5cb9ed39ffc9501cca82fbcea7218bf01d3
author: Sijia Chen <sijchen@cisco.com>
date: Thu Oct 15 06:24:48 EDT 2015
put m_cIdleThreads to CWelsCircleQueue rather than std::map https://rbcommons.com/s/OpenH264/r/1313/
--- a/codec/common/inc/WelsCircleQueue.h
+++ b/codec/common/inc/WelsCircleQueue.h
@@ -66,19 +66,35 @@
}
int32_t push_back (TNodeType* pNode) {
- m_pCurrentQueue[m_iCurrentListEnd] = pNode;
- m_iCurrentListEnd ++;
-
- if (m_iCurrentListEnd == m_iMaxNodeCount) {
- m_iCurrentListEnd = 0;
+ if ((NULL != pNode) && (find (pNode))) { //not checking NULL for easier testing
+ return 1;
}
- if (m_iCurrentListEnd == m_iCurrentListStart) {
- int32_t ret = ExpandList();
- if (ret) {
- return 1;
+ return InternalPushBack (pNode);
+ }
+
+ bool find (TNodeType* pNode) {
+ if (size() > 0) {
+ if (m_iCurrentListEnd > m_iCurrentListStart) {
+ for (int32_t idx = m_iCurrentListStart; idx < m_iCurrentListEnd; idx++) {
+ if (pNode == m_pCurrentQueue[idx]) {
+ return true;
+ }
+ }
+ } else {
+ for (int32_t idx = m_iCurrentListStart; idx < m_iMaxNodeCount; idx++) {
+ if (pNode == m_pCurrentQueue[idx]) {
+ return true;
+ }
+ }
+ for (int32_t idx = 0; idx < m_iCurrentListEnd; idx++) {
+ if (pNode == m_pCurrentQueue[idx]) {
+ return true;
+ }
+ }
+
}
}
- return 0;
+ return false;
}
void pop_front() {
@@ -91,9 +107,28 @@
}
TNodeType* begin() {
- return m_pCurrentQueue[m_iCurrentListStart];
+ if (size() > 0) {
+ return m_pCurrentQueue[m_iCurrentListStart];
+ }
+ return NULL;
}
private:
+ int32_t InternalPushBack (TNodeType* pNode) {
+ m_pCurrentQueue[m_iCurrentListEnd] = pNode;
+ m_iCurrentListEnd ++;
+
+ if (m_iCurrentListEnd == m_iMaxNodeCount) {
+ m_iCurrentListEnd = 0;
+ }
+ if (m_iCurrentListEnd == m_iCurrentListStart) {
+ int32_t ret = ExpandList();
+ if (ret) {
+ return 1;
+ }
+ }
+ return 0;
+ }
+
int32_t ExpandList() {
TNodeType** tmpCurrentTaskQueue = static_cast<TNodeType**> (malloc (m_iMaxNodeCount * 2 * sizeof (TNodeType*)));
if (tmpCurrentTaskQueue == NULL) {
--- a/codec/common/inc/WelsThreadPool.h
+++ b/codec/common/inc/WelsThreadPool.h
@@ -83,7 +83,7 @@
WELS_THREAD_ERROR_CODE CreateIdleThread();
void DestroyThread (CWelsTaskThread* pThread);
- WELS_THREAD_ERROR_CODE AddThreadToIdleMap (CWelsTaskThread* pThread);
+ WELS_THREAD_ERROR_CODE AddThreadToIdleQueue (CWelsTaskThread* pThread);
WELS_THREAD_ERROR_CODE AddThreadToBusyMap (CWelsTaskThread* pThread);
WELS_THREAD_ERROR_CODE RemoveThreadFromBusyMap (CWelsTaskThread* pThread);
void AddTaskToWaitedList (IWelsTask* pTask);
@@ -98,7 +98,7 @@
int32_t m_iMaxThreadNum;
//std::list<IWelsTask*> m_cWaitedTasks;
CWelsCircleQueue<IWelsTask>* m_cWaitedTasks;
- std::map<uintptr_t, CWelsTaskThread*> m_cIdleThreads;
+ CWelsCircleQueue<CWelsTaskThread>* m_cIdleThreads;
std::map<uintptr_t, CWelsTaskThread*> m_cBusyThreads;
IWelsThreadPoolSink* m_pSink;
--- a/codec/common/src/WelsThreadLib.cpp
+++ b/codec/common/src/WelsThreadLib.cpp
@@ -174,6 +174,9 @@
return WELS_THREAD_ERROR_OK;
}
+void WelsSleep (uint32_t dwMilliSecond) {
+ ::Sleep (dwMilliSecond);
+}
WELS_THREAD_ERROR_CODE WelsThreadCreate (WELS_THREAD_HANDLE* thread, LPWELS_THREAD_ROUTINE routine,
void* arg, WELS_THREAD_ATTR attr) {
@@ -332,11 +335,7 @@
}
void WelsSleep (uint32_t dwMilliSecond) {
-#ifdef WIN32
- ::Sleep (dwMilliSecond);
-#else
usleep (dwMilliSecond * 1000);
-#endif
}
WELS_THREAD_ERROR_CODE WelsEventWaitWithTimeOut (WELS_EVENT* event, uint32_t dwMilliseconds) {
--- a/codec/common/src/WelsThreadPool.cpp
+++ b/codec/common/src/WelsThreadPool.cpp
@@ -51,6 +51,7 @@
CWelsThreadPool::CWelsThreadPool (IWelsThreadPoolSink* pSink, int32_t iMaxThreadNum) :
m_pSink (pSink) {
m_cWaitedTasks = new CWelsCircleQueue<IWelsTask>();
+ m_cIdleThreads = new CWelsCircleQueue<CWelsTaskThread>();
m_iMaxThreadNum = 0;
Init (iMaxThreadNum);
@@ -61,6 +62,7 @@
Uninit();
delete m_cWaitedTasks;
+ delete m_cIdleThreads;
}
WELS_THREAD_ERROR_CODE CWelsThreadPool::OnTaskStart (CWelsTaskThread* pThread, IWelsTask* pTask) {
@@ -71,7 +73,7 @@
WELS_THREAD_ERROR_CODE CWelsThreadPool::OnTaskStop (CWelsTaskThread* pThread, IWelsTask* pTask) {
RemoveThreadFromBusyMap (pThread);
- AddThreadToIdleMap (pThread);
+ AddThreadToIdleQueue (pThread);
if (m_pSink) {
m_pSink->OnTaskExecuted (pTask);
@@ -121,10 +123,9 @@
}
m_cLockIdleTasks.Lock();
- std::map<uintptr_t, CWelsTaskThread*>::iterator iter = m_cIdleThreads.begin();
- while (iter != m_cIdleThreads.end()) {
- DestroyThread (iter->second);
- ++ iter;
+ while (m_cIdleThreads->size() > 0) {
+ DestroyThread (m_cIdleThreads->begin());
+ m_cIdleThreads->pop_front();
}
m_cLockIdleTasks.Unlock();
@@ -179,7 +180,7 @@
}
pThread->Start();
- AddThreadToIdleMap (pThread);
+ AddThreadToIdleQueue (pThread);
return WELS_THREAD_ERROR_OK;
}
@@ -191,19 +192,9 @@
return;
}
-WELS_THREAD_ERROR_CODE CWelsThreadPool::AddThreadToIdleMap (CWelsTaskThread* pThread) {
+WELS_THREAD_ERROR_CODE CWelsThreadPool::AddThreadToIdleQueue (CWelsTaskThread* pThread) {
CWelsAutoLock cLock (m_cLockIdleTasks);
-
- uintptr_t id = pThread->GetID();
-
- std::map<uintptr_t, CWelsTaskThread*>::iterator iter = m_cIdleThreads.find (id);
-
- if (iter != m_cIdleThreads.end()) {
- return WELS_THREAD_ERROR_GENERAL;
- }
-
- m_cIdleThreads[id] = pThread;
-
+ m_cIdleThreads->push_back (pThread);
return WELS_THREAD_ERROR_OK;
}
@@ -249,15 +240,12 @@
CWelsTaskThread* CWelsThreadPool::GetIdleThread() {
CWelsAutoLock cLock (m_cLockIdleTasks);
- if (m_cIdleThreads.size() == 0) {
+ if (m_cIdleThreads->size() == 0) {
return NULL;
}
- std::map<uintptr_t, CWelsTaskThread*>::iterator it = m_cIdleThreads.begin();
- CWelsTaskThread* pThread = it->second;
-
- m_cIdleThreads.erase (it);
-
+ CWelsTaskThread* pThread = m_cIdleThreads->begin();
+ m_cIdleThreads->pop_front();
return pThread;
}
@@ -266,7 +254,7 @@
}
int32_t CWelsThreadPool::GetIdleThreadNum() {
- return static_cast<int32_t> (m_cIdleThreads.size());
+ return static_cast<int32_t> (m_cIdleThreads->size());
}
int32_t CWelsThreadPool::GetWaitedTaskNum() {
@@ -275,6 +263,7 @@
IWelsTask* CWelsThreadPool::GetWaitedTask() {
CWelsAutoLock lock (m_cLockWaitedTasks);
+
if (m_cWaitedTasks->size() == 0) {
return NULL;
}
@@ -288,6 +277,7 @@
void CWelsThreadPool::ClearWaitedTasks() {
CWelsAutoLock cLock (m_cLockWaitedTasks);
+
if (m_pSink) {
while (0 != m_cWaitedTasks->size()) {
m_pSink->OnTaskCancelled (m_cWaitedTasks->begin());
--- a/test/build/win32/codec_ut/codec_unittest.vcproj
+++ b/test/build/win32/codec_ut/codec_unittest.vcproj
@@ -831,6 +831,10 @@
Name="common"
>
<File
+ RelativePath="..\..\..\common\CWelsCircleQueue.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\..\common\ExpandPicture.cpp"
>
<FileConfiguration
--- a/test/common/CWelsCircleQueue.cpp
+++ b/test/common/CWelsCircleQueue.cpp
@@ -1,6 +1,6 @@
#include <gtest/gtest.h>
#include "WelsCircleQueue.h"
-#include "WelsTask.h"
+#include "WelsTaskThread.h"
using namespace WelsCommon;
@@ -81,3 +81,115 @@
EXPECT_TRUE (0 == cTaskList.size());
}
+TEST (CWelsCircleQueue, CWelsCircleQueueOnDuplication) {
+ int32_t a, b, c;
+ CWelsCircleQueue<int32_t> cThreadQueue;
+ //CWelsCircleQueue<IWelsTask> cThreadQueue;
+ int32_t* pObject1 = &a;
+ int32_t* pObject2 = &b;
+ int32_t* pObject3 = &c;
+
+ //initial adding
+ EXPECT_TRUE (0 == cThreadQueue.push_back (pObject1));
+ EXPECT_TRUE (0 == cThreadQueue.push_back (pObject2));
+ EXPECT_TRUE (0 == cThreadQueue.push_back (pObject3));
+ EXPECT_TRUE (3 == cThreadQueue.size());
+
+ //try failed adding
+ EXPECT_FALSE (0 == cThreadQueue.push_back (pObject3));
+ EXPECT_TRUE (3 == cThreadQueue.size());
+
+ //try pop
+ EXPECT_TRUE (pObject1 == cThreadQueue.begin());
+ cThreadQueue.pop_front();
+ EXPECT_TRUE (2 == cThreadQueue.size());
+
+ //try what currently in
+ EXPECT_TRUE (cThreadQueue.find (pObject2));
+ EXPECT_FALSE (0 == cThreadQueue.push_back (pObject2));
+ EXPECT_TRUE (cThreadQueue.find (pObject3));
+ EXPECT_FALSE (0 == cThreadQueue.push_back (pObject3));
+ EXPECT_TRUE (2 == cThreadQueue.size());
+
+ //add back
+ EXPECT_TRUE (0 == cThreadQueue.push_back (pObject1));
+ EXPECT_TRUE (3 == cThreadQueue.size());
+
+ //another pop
+ EXPECT_TRUE (pObject2 == cThreadQueue.begin());
+ cThreadQueue.pop_front();
+ cThreadQueue.pop_front();
+ EXPECT_TRUE (1 == cThreadQueue.size());
+
+ EXPECT_FALSE (0 == cThreadQueue.push_back (pObject1));
+ EXPECT_TRUE (1 == cThreadQueue.size());
+
+ EXPECT_TRUE (0 == cThreadQueue.push_back (pObject3));
+ EXPECT_TRUE (2 == cThreadQueue.size());
+
+ //clean-up
+ while (NULL != cThreadQueue.begin()) {
+ cThreadQueue.pop_front();
+ }
+ EXPECT_TRUE (0 == cThreadQueue.size());
+}
+
+#ifndef __APPLE__
+TEST (CWelsCircleQueue, CWelsCircleQueueOnThread) {
+ CWelsCircleQueue<CWelsTaskThread> cThreadQueue;
+ CWelsTaskThread* pTaskThread1 = new CWelsTaskThread (NULL); //this initialization seemed making prob on osx?
+ EXPECT_TRUE (NULL != pTaskThread1);
+ CWelsTaskThread* pTaskThread2 = new CWelsTaskThread (NULL);
+ EXPECT_TRUE (NULL != pTaskThread2);
+ CWelsTaskThread* pTaskThread3 = new CWelsTaskThread (NULL);
+ EXPECT_TRUE (NULL != pTaskThread3);
+
+ //initial adding
+ EXPECT_TRUE (0 == cThreadQueue.push_back (pTaskThread1));
+ EXPECT_TRUE (0 == cThreadQueue.push_back (pTaskThread2));
+ EXPECT_TRUE (0 == cThreadQueue.push_back (pTaskThread3));
+ EXPECT_TRUE (3 == cThreadQueue.size());
+
+ //try failed adding
+ EXPECT_FALSE (0 == cThreadQueue.push_back (pTaskThread3));
+ EXPECT_TRUE (3 == cThreadQueue.size());
+
+ //try pop
+ EXPECT_TRUE (pTaskThread1 == cThreadQueue.begin());
+ cThreadQueue.pop_front();
+ EXPECT_TRUE (2 == cThreadQueue.size());
+
+ //try what currently in
+ EXPECT_TRUE (cThreadQueue.find (pTaskThread2));
+ EXPECT_FALSE (0 == cThreadQueue.push_back (pTaskThread2));
+ EXPECT_TRUE (cThreadQueue.find (pTaskThread3));
+ EXPECT_FALSE (0 == cThreadQueue.push_back (pTaskThread3));
+ EXPECT_TRUE (2 == cThreadQueue.size());
+
+ //add back
+ EXPECT_TRUE (0 == cThreadQueue.push_back (pTaskThread1));
+ EXPECT_TRUE (3 == cThreadQueue.size());
+
+ //another pop
+ EXPECT_TRUE (pTaskThread2 == cThreadQueue.begin());
+ cThreadQueue.pop_front();
+ cThreadQueue.pop_front();
+ EXPECT_TRUE (1 == cThreadQueue.size());
+
+ EXPECT_FALSE (0 == cThreadQueue.push_back (pTaskThread1));
+ EXPECT_TRUE (1 == cThreadQueue.size());
+
+ EXPECT_TRUE (0 == cThreadQueue.push_back (pTaskThread3));
+ EXPECT_TRUE (2 == cThreadQueue.size());
+
+ //clean-up
+ while (NULL != cThreadQueue.begin()) {
+ cThreadQueue.pop_front();
+ }
+ EXPECT_TRUE (0 == cThreadQueue.size());
+
+ delete pTaskThread1;
+ delete pTaskThread2;
+ delete pTaskThread3;
+}
+#endif