swr: [rasterizer core] refactor thread creation
authorTim Rowley <timothy.o.rowley@intel.com>
Fri, 30 Sep 2016 21:05:19 +0000 (16:05 -0500)
committerTim Rowley <timothy.o.rowley@intel.com>
Mon, 3 Oct 2016 14:57:38 +0000 (09:57 -0500)
Create worker pool now computes number of worker threads based on
things like topologies, etc. and creates the pool but doesn't actually
launch the threads. Instead there is a separate start thread pool
function. This allows thread resources to be constructed first before
threads start.

Signed-off-by: Tim Rowley <timothy.o.rowley@intel.com>
src/gallium/drivers/swr/rasterizer/core/api.cpp
src/gallium/drivers/swr/rasterizer/core/threads.cpp
src/gallium/drivers/swr/rasterizer/core/threads.h

index 1702fa0dfdfc19969b9eae9e454c46026eaa0f44..048b9791d6f22eaa345fa1490b2d457a468f8c25 100644 (file)
@@ -159,7 +159,7 @@ HANDLE SwrCreateContext(
 
     pCreateInfo->contextSaveSize = sizeof(API_STATE);
 
-    WakeAllThreads(pContext);
+    StartThreadPool(pContext, &pContext->threadPool);
 
     return (HANDLE)pContext;
 }
index f22f882a458039582d257501ab49a36eff85cd6d..28cd9298967dabc7defba0b2c5b82bd61871bab0 100644 (file)
@@ -718,11 +718,6 @@ DWORD workerThreadMain(LPVOID pData)
     //    the worker can safely increment its oldestDraw counter and move on to the next draw.
     std::unique_lock<std::mutex> lock(pContext->WaitLock, std::defer_lock);
 
-    // Suspend thread immediately. SwrCreateContext or QueueWork will wake this up again.
-    lock.lock();
-    pContext->FifosNotEmpty.wait(lock);
-    lock.unlock();
-
     auto threadHasWork = [&](uint32_t curDraw) { return curDraw != pContext->dcRing.GetHead(); };
 
     uint32_t curDrawBE = 0;
@@ -807,7 +802,11 @@ DWORD workerThreadInit(LPVOID pData)
 }
 template<> DWORD workerThreadInit<false, false>(LPVOID pData) = delete;
 
-void CreateThreadPool(SWR_CONTEXT *pContext, THREAD_POOL *pPool)
+//////////////////////////////////////////////////////////////////////////
+/// @brief Creates thread pool info but doesn't launch threads.
+/// @param pContext - pointer to context
+/// @param pPool - pointer to thread pool object.
+void CreateThreadPool(SWR_CONTEXT* pContext, THREAD_POOL* pPool)
 {
     bindThread(pContext, 0);
 
@@ -953,7 +952,6 @@ void CreateThreadPool(SWR_CONTEXT *pContext, THREAD_POOL *pPool)
             pPool->pThreadData[workerId].htId = 0;
             pPool->pThreadData[workerId].pContext = pContext;
             pPool->pThreadData[workerId].forceBindProcGroup = bForceBindProcGroup;
-            pPool->pThreads[workerId] = new std::thread(workerThreadInit<true, true>, &pPool->pThreadData[workerId]);
 
             pContext->NumBEThreads++;
             pContext->NumFEThreads++;
@@ -999,7 +997,6 @@ void CreateThreadPool(SWR_CONTEXT *pContext, THREAD_POOL *pPool)
                     pPool->pThreadData[workerId].htId = t;
                     pPool->pThreadData[workerId].pContext = pContext;
 
-                    pPool->pThreads[workerId] = new std::thread(workerThreadInit<true, true>, &pPool->pThreadData[workerId]);
                     pContext->NumBEThreads++;
                     pContext->NumFEThreads++;
 
@@ -1007,9 +1004,31 @@ void CreateThreadPool(SWR_CONTEXT *pContext, THREAD_POOL *pPool)
                 }
             }
         }
+        SWR_ASSERT(workerId == pContext->NumWorkerThreads);
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////
+/// @brief Launches worker threads in thread pool.
+/// @param pContext - pointer to context
+/// @param pPool - pointer to thread pool object.
+void StartThreadPool(SWR_CONTEXT* pContext, THREAD_POOL* pPool)
+{
+    if (pContext->threadInfo.SINGLE_THREADED)
+    {
+        return;
+    }
+
+    for (uint32_t workerId = 0; workerId < pContext->NumWorkerThreads; ++workerId)
+    {
+        pPool->pThreads[workerId] = new std::thread(workerThreadInit<true, true>, &pPool->pThreadData[workerId]);
     }
 }
 
+//////////////////////////////////////////////////////////////////////////
+/// @brief Destroys thread pool.
+/// @param pContext - pointer to context
+/// @param pPool - pointer to thread pool object.
 void DestroyThreadPool(SWR_CONTEXT *pContext, THREAD_POOL *pPool)
 {
     if (!pContext->threadInfo.SINGLE_THREADED)
index c802c576fc3408b5bb86fc38ef4f40fbac481399..dac8f86c1dfd4a80280f6aa05dd699f19995b053 100644 (file)
@@ -60,6 +60,7 @@ struct THREAD_POOL
 typedef std::unordered_set<uint32_t> TileSet;
 
 void CreateThreadPool(SWR_CONTEXT *pContext, THREAD_POOL *pPool);
+void StartThreadPool(SWR_CONTEXT* pContext, THREAD_POOL* pPool);
 void DestroyThreadPool(SWR_CONTEXT *pContext, THREAD_POOL *pPool);
 
 // Expose FE and BE worker functions to the API thread if single threaded