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