From cdac0427331442213a2cb8ed5a71057e1bb9793e Mon Sep 17 00:00:00 2001 From: Tim Rowley Date: Fri, 30 Sep 2016 16:05:19 -0500 Subject: [PATCH] swr: [rasterizer core] refactor thread creation 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 --- .../drivers/swr/rasterizer/core/api.cpp | 2 +- .../drivers/swr/rasterizer/core/threads.cpp | 35 ++++++++++++++----- .../drivers/swr/rasterizer/core/threads.h | 1 + 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/gallium/drivers/swr/rasterizer/core/api.cpp b/src/gallium/drivers/swr/rasterizer/core/api.cpp index 1702fa0dfdf..048b9791d6f 100644 --- a/src/gallium/drivers/swr/rasterizer/core/api.cpp +++ b/src/gallium/drivers/swr/rasterizer/core/api.cpp @@ -159,7 +159,7 @@ HANDLE SwrCreateContext( pCreateInfo->contextSaveSize = sizeof(API_STATE); - WakeAllThreads(pContext); + StartThreadPool(pContext, &pContext->threadPool); return (HANDLE)pContext; } diff --git a/src/gallium/drivers/swr/rasterizer/core/threads.cpp b/src/gallium/drivers/swr/rasterizer/core/threads.cpp index f22f882a458..28cd9298967 100644 --- a/src/gallium/drivers/swr/rasterizer/core/threads.cpp +++ b/src/gallium/drivers/swr/rasterizer/core/threads.cpp @@ -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 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(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, &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, &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, &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) diff --git a/src/gallium/drivers/swr/rasterizer/core/threads.h b/src/gallium/drivers/swr/rasterizer/core/threads.h index c802c576fc3..dac8f86c1df 100644 --- a/src/gallium/drivers/swr/rasterizer/core/threads.h +++ b/src/gallium/drivers/swr/rasterizer/core/threads.h @@ -60,6 +60,7 @@ struct THREAD_POOL typedef std::unordered_set 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 -- 2.30.2