u_queue: add util_queue_finish for waiting for previously added jobs
authorNicolai Hähnle <nicolai.haehnle@amd.com>
Sun, 22 Oct 2017 15:38:41 +0000 (17:38 +0200)
committerNicolai Hähnle <nicolai.haehnle@amd.com>
Thu, 9 Nov 2017 10:53:19 +0000 (11:53 +0100)
Schedule one job for every thread, and wait on a barrier inside the job
execution function.

v2: avoid alloca (fixes Windows build error)

Reviewed-by: Marek Olšák <marek.olsak@amd.com> (v1)
src/util/u_queue.c
src/util/u_queue.h

index 8293ec661b0921380ef754c1961b98e63fc6d1c6..706ee8b04d9f3b107827cf9631c8799f4ed0d7f5 100644 (file)
@@ -25,7 +25,9 @@
  */
 
 #include "u_queue.h"
+
 #include "util/u_string.h"
+#include "util/u_thread.h"
 
 static void util_queue_killall_and_wait(struct util_queue *queue);
 
@@ -429,6 +431,39 @@ util_queue_drop_job(struct util_queue *queue, struct util_queue_fence *fence)
       util_queue_fence_wait(fence);
 }
 
+static void
+util_queue_finish_execute(void *data, int num_thread)
+{
+   util_barrier *barrier = data;
+   util_barrier_wait(barrier);
+}
+
+/**
+ * Wait until all previously added jobs have completed.
+ */
+void
+util_queue_finish(struct util_queue *queue)
+{
+   util_barrier barrier;
+   struct util_queue_fence *fences = malloc(queue->num_threads * sizeof(*fences));
+
+   util_barrier_init(&barrier, queue->num_threads);
+
+   for (unsigned i = 0; i < queue->num_threads; ++i) {
+      util_queue_fence_init(&fences[i]);
+      util_queue_add_job(queue, &barrier, &fences[i], util_queue_finish_execute, NULL);
+   }
+
+   for (unsigned i = 0; i < queue->num_threads; ++i) {
+      util_queue_fence_wait(&fences[i]);
+      util_queue_fence_destroy(&fences[i]);
+   }
+
+   util_barrier_destroy(&barrier);
+
+   free(fences);
+}
+
 int64_t
 util_queue_get_thread_time_nano(struct util_queue *queue, unsigned thread_index)
 {
index dfe2153281754dd3398ab8b41edfa08258475608..a54ec7101144756830aca6efa6eb63db757b6084 100644 (file)
@@ -214,6 +214,8 @@ void util_queue_add_job(struct util_queue *queue,
 void util_queue_drop_job(struct util_queue *queue,
                          struct util_queue_fence *fence);
 
+void util_queue_finish(struct util_queue *queue);
+
 int64_t util_queue_get_thread_time_nano(struct util_queue *queue,
                                         unsigned thread_index);