u_queue.c revision 4a06786efd42abfdb0babf65ed4ac59ae58fe4b5
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 if (fence->signalled) 454358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák return; 464358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák 474358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák pipe_mutex_lock(fence->mutex); 484358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák while (!fence->signalled) 494358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák pipe_condvar_wait(fence->cond, fence->mutex); 504358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák pipe_mutex_unlock(fence->mutex); 514358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák} 52562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 53404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšákstruct thread_input { 54404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák struct util_queue *queue; 55404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák int thread_index; 56404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák}; 57404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák 58404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšákstatic PIPE_THREAD_ROUTINE(util_queue_thread_func, input) 59562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák{ 60404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák struct util_queue *queue = ((struct thread_input*)input)->queue; 61404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák int thread_index = ((struct thread_input*)input)->thread_index; 62404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák 63404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák FREE(input); 64562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 652fba0aaa700bbdef37ac5da6da005b24be570e48Marek Olšák if (queue->name) { 662fba0aaa700bbdef37ac5da6da005b24be570e48Marek Olšák char name[16]; 672fba0aaa700bbdef37ac5da6da005b24be570e48Marek Olšák util_snprintf(name, sizeof(name), "%s:%i", queue->name, thread_index); 682fba0aaa700bbdef37ac5da6da005b24be570e48Marek Olšák pipe_thread_setname(name); 692fba0aaa700bbdef37ac5da6da005b24be570e48Marek Olšák } 702fba0aaa700bbdef37ac5da6da005b24be570e48Marek Olšák 71562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák while (1) { 72562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák struct util_queue_job job; 73562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 744a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_mutex_lock(queue->lock); 754a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák assert(queue->num_queued >= 0 && queue->num_queued <= queue->max_jobs); 764a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák 774a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák /* wait if the queue is empty */ 784a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák while (!queue->kill_threads && queue->num_queued == 0) 794a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_condvar_wait(queue->has_queued_cond, queue->lock); 804a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák 814a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák if (queue->kill_threads) { 824a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_mutex_unlock(queue->lock); 83562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák break; 844a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák } 85562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 86d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák job = queue->jobs[queue->read_idx]; 87d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák queue->jobs[queue->read_idx].job = NULL; 88d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák queue->read_idx = (queue->read_idx + 1) % queue->max_jobs; 89562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 904a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák queue->num_queued--; 914a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_condvar_signal(queue->has_space_cond); 924a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_mutex_unlock(queue->lock); 93562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 94562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák if (job.job) { 95404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák queue->execute_job(job.job, thread_index); 964358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák util_queue_fence_signal(job.fence); 97562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák } 98562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák } 99562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 100562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák /* signal remaining jobs before terminating */ 101562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák pipe_mutex_lock(queue->lock); 102d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák while (queue->jobs[queue->read_idx].job) { 1034358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák util_queue_fence_signal(queue->jobs[queue->read_idx].fence); 1044358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák 105d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák queue->jobs[queue->read_idx].job = NULL; 106d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák queue->read_idx = (queue->read_idx + 1) % queue->max_jobs; 107562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák } 108562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák pipe_mutex_unlock(queue->lock); 109562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák return 0; 110562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák} 111562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 112d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšákbool 113562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšákutil_queue_init(struct util_queue *queue, 1142fba0aaa700bbdef37ac5da6da005b24be570e48Marek Olšák const char *name, 115d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák unsigned max_jobs, 116404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák unsigned num_threads, 117404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák void (*execute_job)(void *, int)) 118562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák{ 119404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák unsigned i; 120404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák 121562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák memset(queue, 0, sizeof(*queue)); 1222fba0aaa700bbdef37ac5da6da005b24be570e48Marek Olšák queue->name = name; 123404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák queue->num_threads = num_threads; 124d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák queue->max_jobs = max_jobs; 125d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák 126d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák queue->jobs = (struct util_queue_job*) 127d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák CALLOC(max_jobs, sizeof(struct util_queue_job)); 128d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák if (!queue->jobs) 129d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák goto fail; 130d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák 131562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák queue->execute_job = execute_job; 132562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák pipe_mutex_init(queue->lock); 1334a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák 1344a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák queue->num_queued = 0; 1354a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_condvar_init(queue->has_queued_cond); 1364a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_condvar_init(queue->has_space_cond); 137d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák 138404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák queue->threads = (pipe_thread*)CALLOC(num_threads, sizeof(pipe_thread)); 139404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák if (!queue->threads) 140d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák goto fail; 141d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák 142404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák /* start threads */ 143404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák for (i = 0; i < num_threads; i++) { 144404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák struct thread_input *input = MALLOC_STRUCT(thread_input); 145404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák input->queue = queue; 146404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák input->thread_index = i; 147404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák 148404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák queue->threads[i] = pipe_thread_create(util_queue_thread_func, input); 149404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák 150404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák if (!queue->threads[i]) { 151404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák FREE(input); 152404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák 153404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák if (i == 0) { 154404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák /* no threads created, fail */ 155404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák goto fail; 156404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák } else { 157404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák /* at least one thread created, so use it */ 158404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák queue->num_threads = i+1; 159404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák break; 160404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák } 161404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák } 162404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák } 163d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák return true; 164d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák 165d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšákfail: 166404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák FREE(queue->threads); 167404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák 168d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák if (queue->jobs) { 1694a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_condvar_destroy(queue->has_space_cond); 1704a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_condvar_destroy(queue->has_queued_cond); 171d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák pipe_mutex_destroy(queue->lock); 172d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák FREE(queue->jobs); 173d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák } 174d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák /* also util_queue_is_initialized can be used to check for success */ 175d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák memset(queue, 0, sizeof(*queue)); 176d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák return false; 177562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák} 178562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 179562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšákvoid 180562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšákutil_queue_destroy(struct util_queue *queue) 181562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák{ 182404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák unsigned i; 183404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák 184404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák /* Signal all threads to terminate. */ 1854a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_mutex_lock(queue->lock); 186404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák queue->kill_threads = 1; 1874a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_condvar_broadcast(queue->has_queued_cond); 1884a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_mutex_unlock(queue->lock); 189404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák 190404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák for (i = 0; i < queue->num_threads; i++) 191404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák pipe_thread_wait(queue->threads[i]); 192404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák 1934a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_condvar_destroy(queue->has_space_cond); 1944a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_condvar_destroy(queue->has_queued_cond); 195562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák pipe_mutex_destroy(queue->lock); 196d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák FREE(queue->jobs); 197404d0d50d8aaf60597668e65a2d7c96cdea53aeaMarek Olšák FREE(queue->threads); 198562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák} 199562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 200562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšákvoid 201562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšákutil_queue_fence_init(struct util_queue_fence *fence) 202562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák{ 2034358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák memset(fence, 0, sizeof(*fence)); 2044358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák pipe_mutex_init(fence->mutex); 2054358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák pipe_condvar_init(fence->cond); 2064358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák fence->signalled = true; 207562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák} 208562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 209562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšákvoid 210562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšákutil_queue_fence_destroy(struct util_queue_fence *fence) 211562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák{ 2124358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák pipe_condvar_destroy(fence->cond); 2134358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák pipe_mutex_destroy(fence->mutex); 214562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák} 215562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 216562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšákvoid 217562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšákutil_queue_add_job(struct util_queue *queue, 218562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák void *job, 219562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák struct util_queue_fence *fence) 220562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák{ 221d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák struct util_queue_job *ptr; 2224358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák 2234358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák assert(fence->signalled); 2244358f6dd130680d60d48d6646959c11c8d7ca13dMarek Olšák fence->signalled = false; 225562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 2264a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_mutex_lock(queue->lock); 2274a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák assert(queue->num_queued >= 0 && queue->num_queued <= queue->max_jobs); 2284a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák 229562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák /* if the queue is full, wait until there is space */ 2304a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák while (queue->num_queued == queue->max_jobs) 2314a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_condvar_wait(queue->has_space_cond, queue->lock); 232562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák 233d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák ptr = &queue->jobs[queue->write_idx]; 234d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák assert(ptr->job == NULL); 235d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák ptr->job = job; 236d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák ptr->fence = fence; 237d8367e91f2e3d8426e77674b39f36c09ed9992ecMarek Olšák queue->write_idx = (queue->write_idx + 1) % queue->max_jobs; 2384a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák 2394a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák queue->num_queued++; 2404a06786efd42abfdb0babf65ed4ac59ae58fe4b5Marek Olšák pipe_condvar_signal(queue->has_queued_cond); 241562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák pipe_mutex_unlock(queue->lock); 242562cb03d76e4788d1d832f069e2c2f716e344fa4Marek Olšák} 243