~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/gallium/drivers/llvmpipe/lp_cs_tpool.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**************************************************************************
2
 
 *
3
 
 * Copyright 2019 Red Hat.
4
 
 * All Rights Reserved.
5
 
 *
6
 
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 
 * copy of this software and associated documentation files (the "Software"),
8
 
 * to deal in the Software without restriction, including without limitation
9
 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
 
 * and/or sell copies of the Software, and to permit persons to whom the
11
 
 * Software is furnished to do so, subject to the following conditions:
12
 
 *
13
 
 * The above copyright notice and this permission notice shall be included
14
 
 * in all copies or substantial portions of the Software.
15
 
 *
16
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17
 
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19
 
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
 
 * SOFTWARE.
23
 
 *
24
 
 **************************************************************************/
25
 
 
26
 
/**
27
 
 * compute shader thread pool.
28
 
 * based on threadpool.c but modified heavily to be compute shader tuned.
29
 
 */
30
 
 
31
 
#include "util/u_thread.h"
32
 
#include "util/u_memory.h"
33
 
#include "lp_cs_tpool.h"
34
 
 
35
 
static int
36
 
lp_cs_tpool_worker(void *data)
37
 
{
38
 
   struct lp_cs_tpool *pool = data;
39
 
   struct lp_cs_local_mem lmem;
40
 
 
41
 
   memset(&lmem, 0, sizeof(lmem));
42
 
   mtx_lock(&pool->m);
43
 
 
44
 
   while (!pool->shutdown) {
45
 
      struct lp_cs_tpool_task *task;
46
 
      unsigned iter_per_thread;
47
 
 
48
 
      while (list_is_empty(&pool->workqueue) && !pool->shutdown)
49
 
         cnd_wait(&pool->new_work, &pool->m);
50
 
 
51
 
      if (pool->shutdown)
52
 
         break;
53
 
 
54
 
      task = list_first_entry(&pool->workqueue, struct lp_cs_tpool_task,
55
 
                              list);
56
 
 
57
 
      unsigned this_iter = task->iter_start;
58
 
 
59
 
      iter_per_thread = task->iter_per_thread;
60
 
 
61
 
      if (task->iter_remainder &&
62
 
          task->iter_start + task->iter_remainder == task->iter_total) {
63
 
         task->iter_remainder--;
64
 
         iter_per_thread = 1;
65
 
      }
66
 
 
67
 
      task->iter_start += iter_per_thread;
68
 
 
69
 
      if (task->iter_start == task->iter_total)
70
 
         list_del(&task->list);
71
 
 
72
 
      mtx_unlock(&pool->m);
73
 
      for (unsigned i = 0; i < iter_per_thread; i++)
74
 
         task->work(task->data, this_iter + i, &lmem);
75
 
 
76
 
      mtx_lock(&pool->m);
77
 
      task->iter_finished += iter_per_thread;
78
 
      if (task->iter_finished == task->iter_total)
79
 
         cnd_broadcast(&task->finish);
80
 
   }
81
 
   mtx_unlock(&pool->m);
82
 
   FREE(lmem.local_mem_ptr);
83
 
   return 0;
84
 
}
85
 
 
86
 
struct lp_cs_tpool *
87
 
lp_cs_tpool_create(unsigned num_threads)
88
 
{
89
 
   struct lp_cs_tpool *pool = CALLOC_STRUCT(lp_cs_tpool);
90
 
 
91
 
   if (!pool)
92
 
      return NULL;
93
 
 
94
 
   (void) mtx_init(&pool->m, mtx_plain);
95
 
   cnd_init(&pool->new_work);
96
 
 
97
 
   list_inithead(&pool->workqueue);
98
 
   assert (num_threads <= LP_MAX_THREADS);
99
 
   pool->num_threads = num_threads;
100
 
   for (unsigned i = 0; i < num_threads; i++)
101
 
      pool->threads[i] = u_thread_create(lp_cs_tpool_worker, pool);
102
 
   return pool;
103
 
}
104
 
 
105
 
void
106
 
lp_cs_tpool_destroy(struct lp_cs_tpool *pool)
107
 
{
108
 
   if (!pool)
109
 
      return;
110
 
 
111
 
   mtx_lock(&pool->m);
112
 
   pool->shutdown = true;
113
 
   cnd_broadcast(&pool->new_work);
114
 
   mtx_unlock(&pool->m);
115
 
 
116
 
   for (unsigned i = 0; i < pool->num_threads; i++) {
117
 
      thrd_join(pool->threads[i], NULL);
118
 
   }
119
 
 
120
 
   cnd_destroy(&pool->new_work);
121
 
   mtx_destroy(&pool->m);
122
 
   FREE(pool);
123
 
}
124
 
 
125
 
struct lp_cs_tpool_task *
126
 
lp_cs_tpool_queue_task(struct lp_cs_tpool *pool,
127
 
                       lp_cs_tpool_task_func work, void *data, int num_iters)
128
 
{
129
 
   struct lp_cs_tpool_task *task;
130
 
 
131
 
   if (pool->num_threads == 0) {
132
 
      struct lp_cs_local_mem lmem;
133
 
 
134
 
      memset(&lmem, 0, sizeof(lmem));
135
 
      for (unsigned t = 0; t < num_iters; t++) {
136
 
         work(data, t, &lmem);
137
 
      }
138
 
      FREE(lmem.local_mem_ptr);
139
 
      return NULL;
140
 
   }
141
 
   task = CALLOC_STRUCT(lp_cs_tpool_task);
142
 
   if (!task) {
143
 
      return NULL;
144
 
   }
145
 
 
146
 
   task->work = work;
147
 
   task->data = data;
148
 
   task->iter_total = num_iters;
149
 
 
150
 
   task->iter_per_thread = num_iters / pool->num_threads;
151
 
   task->iter_remainder = num_iters % pool->num_threads;
152
 
 
153
 
   cnd_init(&task->finish);
154
 
 
155
 
   mtx_lock(&pool->m);
156
 
 
157
 
   list_addtail(&task->list, &pool->workqueue);
158
 
 
159
 
   cnd_broadcast(&pool->new_work);
160
 
   mtx_unlock(&pool->m);
161
 
   return task;
162
 
}
163
 
 
164
 
void
165
 
lp_cs_tpool_wait_for_task(struct lp_cs_tpool *pool,
166
 
                          struct lp_cs_tpool_task **task_handle)
167
 
{
168
 
   struct lp_cs_tpool_task *task = *task_handle;
169
 
 
170
 
   if (!pool || !task)
171
 
      return;
172
 
 
173
 
   mtx_lock(&pool->m);
174
 
   while (task->iter_finished < task->iter_total)
175
 
      cnd_wait(&task->finish, &pool->m);
176
 
   mtx_unlock(&pool->m);
177
 
 
178
 
   cnd_destroy(&task->finish);
179
 
   FREE(task);
180
 
   *task_handle = NULL;
181
 
}