2 * Copyright © 2012 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 #include "swapchain9.h"
28 #include "nine_helpers.h"
29 #include "nine_pipe.h"
30 #include "nine_dump.h"
32 #include "util/u_inlines.h"
33 #include "util/u_surface.h"
34 #include "hud/hud_context.h"
35 #include "state_tracker/drm_driver.h"
37 #include "os/os_thread.h"
38 #include "threadpool.h"
41 threadpool_worker(void *data
)
43 struct threadpool
*pool
= data
;
45 pthread_mutex_lock(&pool
->m
);
47 while (!pool
->shutdown
) {
48 struct threadpool_task
*task
;
50 /* Block (dropping the lock) until new work arrives for us. */
51 while (!pool
->workqueue
&& !pool
->shutdown
)
52 pthread_cond_wait(&pool
->new_work
, &pool
->m
);
55 pthread_mutex_unlock(&pool
->m
);
59 /* Pull the first task from the list. We don't free it -- it now lacks
60 * a reference other than the worker creator's, whose responsibility it
61 * is to call threadpool_wait_for_work() to free it.
63 task
= pool
->workqueue
;
64 pool
->workqueue
= task
->next
;
66 /* Call the task's work func. */
67 pthread_mutex_unlock(&pool
->m
);
68 task
->work(task
->data
);
69 pthread_mutex_lock(&pool
->m
);
70 task
->finished
= TRUE
;
71 pthread_cond_broadcast(&task
->finish
);
74 pthread_mutex_unlock(&pool
->m
);
80 _mesa_threadpool_create(void)
82 struct threadpool
*pool
= calloc(1, sizeof(*pool
));
87 pthread_mutex_init(&pool
->m
, NULL
);
88 pthread_cond_init(&pool
->new_work
, NULL
);
90 pthread_create(&pool
->thread
, NULL
, threadpool_worker
, pool
);
96 _mesa_threadpool_destroy(struct threadpool
*pool
)
101 pthread_mutex_lock(&pool
->m
);
102 pool
->shutdown
= TRUE
;
103 pthread_cond_broadcast(&pool
->new_work
);
104 pthread_mutex_unlock(&pool
->m
);
106 pthread_join(pool
->thread
, NULL
);
108 pthread_cond_destroy(&pool
->new_work
);
109 pthread_mutex_destroy(&pool
->m
);
114 * Queues a request for the work function to be asynchronously executed by the
117 * The work func will get the "data" argument as its parameter -- any
118 * communication between the caller and the work function will occur through
121 * If there is an error, the work function is called immediately and NULL is
124 struct threadpool_task
*
125 _mesa_threadpool_queue_task(struct threadpool
*pool
,
126 threadpool_task_func work
, void *data
)
128 struct threadpool_task
*task
, *previous
;
135 task
= calloc(1, sizeof(*task
));
144 pthread_cond_init(&task
->finish
, NULL
);
146 pthread_mutex_lock(&pool
->m
);
148 if (!pool
->workqueue
) {
149 pool
->workqueue
= task
;
151 previous
= pool
->workqueue
;
152 while (previous
&& previous
->next
)
153 previous
= previous
->next
;
155 previous
->next
= task
;
157 pthread_cond_signal(&pool
->new_work
);
158 pthread_mutex_unlock(&pool
->m
);
164 * Blocks on the completion of the given task and frees the task.
167 _mesa_threadpool_wait_for_task(struct threadpool
*pool
,
168 struct threadpool_task
**task_handle
)
170 struct threadpool_task
*task
= *task_handle
;
175 pthread_mutex_lock(&pool
->m
);
176 while (!task
->finished
)
177 pthread_cond_wait(&task
->finish
, &pool
->m
);
178 pthread_mutex_unlock(&pool
->m
);
180 pthread_cond_destroy(&task
->finish
);