util/u_queue: add UTIL_QUEUE_INIT_SCALE_THREADS flag
authorPierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Wed, 9 Jun 2021 11:49:23 +0000 (13:49 +0200)
committerPierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Thu, 17 Jun 2021 07:11:59 +0000 (09:11 +0200)
This flag allow to create a single thread initially, but set
max_thread to the request thread count.

If the queue is full and num_threads is lower than max_threads,
we spawn a new thread to help process the queue faster.

This avoid creating N threads at queue creation time.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11296>

src/util/u_queue.c
src/util/u_queue.h

index 236a484..deb6a79 100644 (file)
@@ -441,7 +441,7 @@ util_queue_init(struct util_queue *queue,
 
    queue->flags = flags;
    queue->max_threads = num_threads;
-   queue->num_threads = num_threads;
+   queue->num_threads = (flags & UTIL_QUEUE_INIT_SCALE_THREADS) ? 1 : num_threads;
    queue->max_jobs = max_jobs;
    queue->global_data = global_data;
 
@@ -457,12 +457,12 @@ util_queue_init(struct util_queue *queue,
    cnd_init(&queue->has_queued_cond);
    cnd_init(&queue->has_space_cond);
 
-   queue->threads = (thrd_t*) calloc(num_threads, sizeof(thrd_t));
+   queue->threads = (thrd_t*) calloc(queue->max_threads, sizeof(thrd_t));
    if (!queue->threads)
       goto fail;
 
    /* start threads */
-   for (i = 0; i < num_threads; i++) {
+   for (i = 0; i < queue->num_threads; i++) {
       if (!util_queue_create_thread(queue, i)) {
          if (i == 0) {
             /* no threads created, fail */
@@ -568,7 +568,14 @@ util_queue_add_job(struct util_queue *queue,
 
    assert(queue->num_queued >= 0 && queue->num_queued <= queue->max_jobs);
 
+
    if (queue->num_queued == queue->max_jobs) {
+      if ((queue->flags & UTIL_QUEUE_INIT_SCALE_THREADS) &&
+          execute != util_queue_finish_execute &&
+          queue->num_threads < queue->max_threads) {
+         util_queue_adjust_num_threads(queue, queue->num_threads + 1);
+      }
+
       if (queue->flags & UTIL_QUEUE_INIT_RESIZE_IF_FULL &&
           queue->total_jobs_size + job_size < S_256MB) {
          /* If the queue is full, make it larger to avoid waiting for a free
index 704d6c5..793120a 100644 (file)
@@ -49,6 +49,7 @@ extern "C" {
 #define UTIL_QUEUE_INIT_USE_MINIMUM_PRIORITY      (1 << 0)
 #define UTIL_QUEUE_INIT_RESIZE_IF_FULL            (1 << 1)
 #define UTIL_QUEUE_INIT_SET_FULL_THREAD_AFFINITY  (1 << 2)
+#define UTIL_QUEUE_INIT_SCALE_THREADS             (1 << 3)
 
 #if UTIL_FUTEX_SUPPORTED
 #define UTIL_QUEUE_FENCE_FUTEX