u_queue.c revision 374aa2bb27efbd5e20daee09b6aea2a86b4775cd
1562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák/* 2562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák * Copyright © 2016 Advanced Micro Devices, Inc. 3562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák * All Rights Reserved. 4562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák * 5562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák * Permission is hereby granted, free of charge, to any person obtaining 6562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák * a copy of this software and associated documentation files (the 7562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák * "Software"), to deal in the Software without restriction, including 8562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák * without limitation the rights to use, copy, modify, merge, publish, 9562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák * distribute, sub license, and/or sell copies of the Software, and to 10562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák * permit persons to whom the Software is furnished to do so, subject to 11562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák * the following conditions: 12562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák * 13562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 15562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 16562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS 17562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák * USE OR OTHER DEALINGS IN THE SOFTWARE. 21562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák * 22562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák * The above copyright notice and this permission notice (including the 23562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák * next paragraph) shall be included in all copies or substantial portions 24562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák * of the Software. 25562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák */ 26562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 27562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák#include "u_queue.h" 28404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák#include "u_memory.h" 292fba0aaa700bbdef37ac5da6da005b24be570e48Marek Olšák#include "u_string.h" 304358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák#include "os/os_time.h" 314358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák 324358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšákstatic void 334358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšákutil_queue_fence_signal(struct util_queue_fence *fence) 344358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák{ 354358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák pipe_mutex_lock(fence->mutex); 364358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák fence->signalled = true; 374358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák pipe_condvar_broadcast(fence->cond); 384358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák pipe_mutex_unlock(fence->mutex); 394358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák} 404358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák 414358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšákvoid 424358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšákutil_queue_job_wait(struct util_queue_fence *fence) 434358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák{ 444358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák pipe_mutex_lock(fence->mutex); 454358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák while (!fence->signalled) 464358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák pipe_condvar_wait(fence->cond, fence->mutex); 474358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák pipe_mutex_unlock(fence->mutex); 484358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák} 49562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 50404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšákstruct thread_input { 51404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák struct util_queue *queue; 52404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák int thread_index; 53404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák}; 54404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák 55404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšákstatic PIPE_THREAD_ROUTINE(util_queue_thread_func, input) 56562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák{ 57404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák struct util_queue *queue = ((struct thread_input*)input)->queue; 58404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák int thread_index = ((struct thread_input*)input)->thread_index; 59404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák 60404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák FREE(input); 61562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 622fba0aaa700bbdef37ac5da6da005b24be570e48Marek Olšák if (queue->name) { 632fba0aaa700bbdef37ac5da6da005b24be570e48Marek Olšák char name[16]; 642fba0aaa700bbdef37ac5da6da005b24be570e48Marek Olšák util_snprintf(name, sizeof(name), "%s:%i", queue->name, thread_index); 652fba0aaa700bbdef37ac5da6da005b24be570e48Marek Olšák pipe_thread_setname(name); 662fba0aaa700bbdef37ac5da6da005b24be570e48Marek Olšák } 672fba0aaa700bbdef37ac5da6da005b24be570e48Marek Olšák 68562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák while (1) { 69562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák struct util_queue_job job; 70562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 714a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_mutex_lock(queue->lock); 724a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák assert(queue->num_queued >= 0 && queue->num_queued <= queue->max_jobs); 734a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák 744a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák /* wait if the queue is empty */ 754a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák while (!queue->kill_threads && queue->num_queued == 0) 764a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_condvar_wait(queue->has_queued_cond, queue->lock); 774a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák 784a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák if (queue->kill_threads) { 794a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_mutex_unlock(queue->lock); 80562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák break; 814a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák } 82562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 83d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák job = queue->jobs[queue->read_idx]; 84cbb5adb90893a7c03f96f72f0665766a4007affdMarek Olšák memset(&queue->jobs[queue->read_idx], 0, sizeof(struct util_queue_job)); 85d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák queue->read_idx = (queue->read_idx + 1) % queue->max_jobs; 86562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 874a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák queue->num_queued--; 884a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_condvar_signal(queue->has_space_cond); 894a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_mutex_unlock(queue->lock); 90562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 91562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák if (job.job) { 92cbb5adb90893a7c03f96f72f0665766a4007affdMarek Olšák job.execute(job.job, thread_index); 934358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák util_queue_fence_signal(job.fence); 94562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák } 95562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák } 96562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 97562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák /* signal remaining jobs before terminating */ 98562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák pipe_mutex_lock(queue->lock); 99d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák while (queue->jobs[queue->read_idx].job) { 1004358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák util_queue_fence_signal(queue->jobs[queue->read_idx].fence); 1014358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák 102d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák queue->jobs[queue->read_idx].job = NULL; 103d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák queue->read_idx = (queue->read_idx + 1) % queue->max_jobs; 104562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák } 105562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák pipe_mutex_unlock(queue->lock); 106562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák return 0; 107562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák} 108562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 109d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšákbool 110562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšákutil_queue_init(struct util_queue *queue, 1112fba0aaa700bbdef37ac5da6da005b24be570e48Marek Olšák const char *name, 112d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák unsigned max_jobs, 113cbb5adb90893a7c03f96f72f0665766a4007affdMarek Olšák unsigned num_threads) 114562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák{ 115404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák unsigned i; 116404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák 117562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák memset(queue, 0, sizeof(*queue)); 1182fba0aaa700bbdef37ac5da6da005b24be570e48Marek Olšák queue->name = name; 119404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák queue->num_threads = num_threads; 120d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák queue->max_jobs = max_jobs; 121d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák 122d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák queue->jobs = (struct util_queue_job*) 123d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák CALLOC(max_jobs, sizeof(struct util_queue_job)); 124d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák if (!queue->jobs) 125d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák goto fail; 126d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák 127562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák pipe_mutex_init(queue->lock); 1284a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák 1294a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák queue->num_queued = 0; 1304a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_condvar_init(queue->has_queued_cond); 1314a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_condvar_init(queue->has_space_cond); 132d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák 133404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák queue->threads = (pipe_thread*)CALLOC(num_threads, sizeof(pipe_thread)); 134404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák if (!queue->threads) 135d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák goto fail; 136d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák 137404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák /* start threads */ 138404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák for (i = 0; i < num_threads; i++) { 139404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák struct thread_input *input = MALLOC_STRUCT(thread_input); 140404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák input->queue = queue; 141404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák input->thread_index = i; 142404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák 143404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák queue->threads[i] = pipe_thread_create(util_queue_thread_func, input); 144404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák 145404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák if (!queue->threads[i]) { 146404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák FREE(input); 147404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák 148404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák if (i == 0) { 149404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák /* no threads created, fail */ 150404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák goto fail; 151404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák } else { 152404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák /* at least one thread created, so use it */ 153404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák queue->num_threads = i+1; 154404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák break; 155404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák } 156404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák } 157404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák } 158d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák return true; 159d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák 160d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšákfail: 161404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák FREE(queue->threads); 162404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák 163d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák if (queue->jobs) { 1644a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_condvar_destroy(queue->has_space_cond); 1654a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_condvar_destroy(queue->has_queued_cond); 166d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák pipe_mutex_destroy(queue->lock); 167d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák FREE(queue->jobs); 168d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák } 169d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák /* also util_queue_is_initialized can be used to check for success */ 170d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák memset(queue, 0, sizeof(*queue)); 171d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák return false; 172562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák} 173562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 174562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšákvoid 175562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšákutil_queue_destroy(struct util_queue *queue) 176562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák{ 177404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák unsigned i; 178404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák 179404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák /* Signal all threads to terminate. */ 1804a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_mutex_lock(queue->lock); 181404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák queue->kill_threads = 1; 1824a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_condvar_broadcast(queue->has_queued_cond); 1834a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_mutex_unlock(queue->lock); 184404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák 185404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák for (i = 0; i < queue->num_threads; i++) 186404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák pipe_thread_wait(queue->threads[i]); 187404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák 1884a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_condvar_destroy(queue->has_space_cond); 1894a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_condvar_destroy(queue->has_queued_cond); 190562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák pipe_mutex_destroy(queue->lock); 191d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák FREE(queue->jobs); 192404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák FREE(queue->threads); 193562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák} 194562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 195562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšákvoid 196562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšákutil_queue_fence_init(struct util_queue_fence *fence) 197562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák{ 1984358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák memset(fence, 0, sizeof(*fence)); 1994358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák pipe_mutex_init(fence->mutex); 2004358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák pipe_condvar_init(fence->cond); 2014358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák fence->signalled = true; 202562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák} 203562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 204562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšákvoid 205562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšákutil_queue_fence_destroy(struct util_queue_fence *fence) 206562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák{ 207374aa2bb27efbd5e20daee09b6aea2a86b4775cdNicolai Hähnle assert(fence->signalled); 2084358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák pipe_condvar_destroy(fence->cond); 2094358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák pipe_mutex_destroy(fence->mutex); 210562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák} 211562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 212562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšákvoid 213562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšákutil_queue_add_job(struct util_queue *queue, 214562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák void *job, 215cbb5adb90893a7c03f96f72f0665766a4007affdMarek Olšák struct util_queue_fence *fence, 216cbb5adb90893a7c03f96f72f0665766a4007affdMarek Olšák util_queue_execute_func execute) 217562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák{ 218d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák struct util_queue_job *ptr; 2194358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák 2204358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák assert(fence->signalled); 2214358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák fence->signalled = false; 222562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 2234a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_mutex_lock(queue->lock); 2244a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák assert(queue->num_queued >= 0 && queue->num_queued <= queue->max_jobs); 2254a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák 226562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák /* if the queue is full, wait until there is space */ 2274a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák while (queue->num_queued == queue->max_jobs) 2284a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_condvar_wait(queue->has_space_cond, queue->lock); 229562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 230d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák ptr = &queue->jobs[queue->write_idx]; 231d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák assert(ptr->job == NULL); 232d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák ptr->job = job; 233d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák ptr->fence = fence; 234cbb5adb90893a7c03f96f72f0665766a4007affdMarek Olšák ptr->execute = execute; 235d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák queue->write_idx = (queue->write_idx + 1) % queue->max_jobs; 2364a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák 2374a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák queue->num_queued++; 2384a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_condvar_signal(queue->has_queued_cond); 239562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák pipe_mutex_unlock(queue->lock); 240562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák} 241