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