Path: blob/21.2-virgl/src/gallium/drivers/llvmpipe/lp_cs_tpool.c
4570 views
/**************************************************************************1*2* Copyright 2019 Red Hat.3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the "Software"),7* to deal in the Software without restriction, including without limitation8* the rights to use, copy, modify, merge, publish, distribute, sublicense,9* and/or sell copies of the Software, and to permit persons to whom the10* Software is furnished to do so, subject to the following conditions:11*12* The above copyright notice and this permission notice shall be included13* in all copies or substantial portions of the Software.14*15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS16* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL18* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER19* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,20* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE21* SOFTWARE.22*23**************************************************************************/2425/**26* compute shader thread pool.27* based on threadpool.c but modified heavily to be compute shader tuned.28*/2930#include "util/u_thread.h"31#include "util/u_memory.h"32#include "lp_cs_tpool.h"3334static int35lp_cs_tpool_worker(void *data)36{37struct lp_cs_tpool *pool = data;38struct lp_cs_local_mem lmem;3940memset(&lmem, 0, sizeof(lmem));41mtx_lock(&pool->m);4243while (!pool->shutdown) {44struct lp_cs_tpool_task *task;4546while (list_is_empty(&pool->workqueue) && !pool->shutdown)47cnd_wait(&pool->new_work, &pool->m);4849if (pool->shutdown)50break;5152task = list_first_entry(&pool->workqueue, struct lp_cs_tpool_task,53list);54unsigned this_iter = task->iter_start++;5556if (task->iter_start == task->iter_total)57list_del(&task->list);5859mtx_unlock(&pool->m);60task->work(task->data, this_iter, &lmem);61mtx_lock(&pool->m);62task->iter_finished++;63if (task->iter_finished == task->iter_total)64cnd_broadcast(&task->finish);65}66mtx_unlock(&pool->m);67FREE(lmem.local_mem_ptr);68return 0;69}7071struct lp_cs_tpool *72lp_cs_tpool_create(unsigned num_threads)73{74struct lp_cs_tpool *pool = CALLOC_STRUCT(lp_cs_tpool);7576if (!pool)77return NULL;7879(void) mtx_init(&pool->m, mtx_plain);80cnd_init(&pool->new_work);8182list_inithead(&pool->workqueue);83assert (num_threads <= LP_MAX_THREADS);84pool->num_threads = num_threads;85for (unsigned i = 0; i < num_threads; i++)86pool->threads[i] = u_thread_create(lp_cs_tpool_worker, pool);87return pool;88}8990void91lp_cs_tpool_destroy(struct lp_cs_tpool *pool)92{93if (!pool)94return;9596mtx_lock(&pool->m);97pool->shutdown = true;98cnd_broadcast(&pool->new_work);99mtx_unlock(&pool->m);100101for (unsigned i = 0; i < pool->num_threads; i++) {102thrd_join(pool->threads[i], NULL);103}104105cnd_destroy(&pool->new_work);106mtx_destroy(&pool->m);107FREE(pool);108}109110struct lp_cs_tpool_task *111lp_cs_tpool_queue_task(struct lp_cs_tpool *pool,112lp_cs_tpool_task_func work, void *data, int num_iters)113{114struct lp_cs_tpool_task *task;115116if (pool->num_threads == 0) {117struct lp_cs_local_mem lmem;118119memset(&lmem, 0, sizeof(lmem));120for (unsigned t = 0; t < num_iters; t++) {121work(data, t, &lmem);122}123return NULL;124}125task = CALLOC_STRUCT(lp_cs_tpool_task);126if (!task) {127return NULL;128}129130task->work = work;131task->data = data;132task->iter_total = num_iters;133cnd_init(&task->finish);134135mtx_lock(&pool->m);136137list_addtail(&task->list, &pool->workqueue);138139cnd_broadcast(&pool->new_work);140mtx_unlock(&pool->m);141return task;142}143144void145lp_cs_tpool_wait_for_task(struct lp_cs_tpool *pool,146struct lp_cs_tpool_task **task_handle)147{148struct lp_cs_tpool_task *task = *task_handle;149150if (!pool || !task)151return;152153mtx_lock(&pool->m);154while (task->iter_finished < task->iter_total)155cnd_wait(&task->finish, &pool->m);156mtx_unlock(&pool->m);157158cnd_destroy(&task->finish);159FREE(task);160*task_handle = NULL;161}162163164