[Mesa-dev] [PATCHv2 07/13] glsl: add a singleton GLSL thread pool
Chia-I Wu
olvaffe at gmail.com
Wed Jul 9 00:47:48 PDT 2014
This thread pool will be used by contexts to queue compilation tasks.
Signed-off-by: Chia-I Wu <olv at lunarg.com>
---
src/glsl/glsl_parser_extras.cpp | 4 +++
src/glsl/threadpool.c | 72 +++++++++++++++++++++++++++++++++++++++++
src/glsl/threadpool.h | 9 ++++++
3 files changed, 85 insertions(+)
diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp
index ad31469..cb7d59e 100644
--- a/src/glsl/glsl_parser_extras.cpp
+++ b/src/glsl/glsl_parser_extras.cpp
@@ -37,6 +37,7 @@ extern "C" {
#include "glsl_parser.h"
#include "ir_optimization.h"
#include "loop_analysis.h"
+#include "threadpool.h"
/**
* Format a short human-readable description of the given GLSL version.
@@ -1599,6 +1600,8 @@ extern "C" {
void
_mesa_destroy_shader_compiler(void)
{
+ _mesa_glsl_destroy_threadpool();
+
_mesa_destroy_shader_compiler_caches();
_mesa_glsl_release_types();
@@ -1612,6 +1615,7 @@ _mesa_destroy_shader_compiler(void)
void
_mesa_destroy_shader_compiler_caches(void)
{
+ _mesa_glsl_wait_threadpool();
_mesa_glsl_release_builtin_functions();
}
diff --git a/src/glsl/threadpool.c b/src/glsl/threadpool.c
index c069fd3..d6ed8c1 100644
--- a/src/glsl/threadpool.c
+++ b/src/glsl/threadpool.c
@@ -55,6 +55,7 @@ struct _mesa_threadpool_task {
struct _mesa_threadpool {
mtx_t mutex;
int refcnt;
+ bool shutdown;
enum _mesa_threadpool_control thread_control;
thrd_t *threads;
@@ -168,6 +169,12 @@ _mesa_threadpool_queue_task(struct _mesa_threadpool *pool,
mtx_lock(&pool->mutex);
+ if (unlikely(pool->shutdown)) {
+ mtx_unlock(&pool->mutex);
+ free(task);
+ return NULL;
+ }
+
/* someone is joining with the threads */
while (unlikely(pool->thread_control != MESA_THREADPOOL_NORMAL))
cnd_wait(&pool->thread_joined, &pool->mutex);
@@ -379,6 +386,17 @@ _mesa_threadpool_join(struct _mesa_threadpool *pool, bool graceful)
}
/**
+ * After this call, no task can be queued.
+ */
+static void
+_mesa_threadpool_set_shutdown(struct _mesa_threadpool *pool)
+{
+ mtx_lock(&pool->mutex);
+ pool->shutdown = true;
+ mtx_unlock(&pool->mutex);
+}
+
+/**
* Decrease the reference count. Destroy \p pool when the reference count
* reaches zero.
*/
@@ -474,3 +492,57 @@ _mesa_threadpool_create(int max_threads)
return pool;
}
+
+static mtx_t threadpool_lock = _MTX_INITIALIZER_NP;
+static struct _mesa_threadpool *threadpool;
+
+/**
+ * Get the singleton GLSL thread pool. \p max_threads is honored only by the
+ * first call to this function.
+ */
+struct _mesa_threadpool *
+_mesa_glsl_get_threadpool(int max_threads)
+{
+ mtx_lock(&threadpool_lock);
+ if (!threadpool)
+ threadpool = _mesa_threadpool_create(max_threads);
+ if (threadpool)
+ _mesa_threadpool_ref(threadpool);
+ mtx_unlock(&threadpool_lock);
+
+ return threadpool;
+}
+
+/**
+ * Wait until all tasks are completed and threads are joined.
+ */
+void
+_mesa_glsl_wait_threadpool(void)
+{
+ mtx_lock(&threadpool_lock);
+ if (threadpool)
+ _mesa_threadpool_join(threadpool, true);
+ mtx_unlock(&threadpool_lock);
+}
+
+/**
+ * Destroy the GLSL thread pool.
+ */
+void
+_mesa_glsl_destroy_threadpool(void)
+{
+ mtx_lock(&threadpool_lock);
+ if (threadpool) {
+ /*
+ * This is called from _mesa_destroy_shader_compiler(). No new task is
+ * allowed since this point. But contexts, who also own references to
+ * the pool, can still complete tasks that have been queued.
+ */
+ _mesa_threadpool_set_shutdown(threadpool);
+
+ _mesa_threadpool_join(threadpool, false);
+ _mesa_threadpool_unref(threadpool);
+ threadpool = NULL;
+ }
+ mtx_unlock(&threadpool_lock);
+}
diff --git a/src/glsl/threadpool.h b/src/glsl/threadpool.h
index 48e4a47..b1a8ea8 100644
--- a/src/glsl/threadpool.h
+++ b/src/glsl/threadpool.h
@@ -60,6 +60,15 @@ bool
_mesa_threadpool_complete_task(struct _mesa_threadpool *pool,
struct _mesa_threadpool_task *task);
+struct _mesa_threadpool *
+_mesa_glsl_get_threadpool(int max_threads);
+
+void
+_mesa_glsl_wait_threadpool(void);
+
+void
+_mesa_glsl_destroy_threadpool(void);
+
#ifdef __cplusplus
}
#endif
--
2.0.0.rc2
More information about the mesa-dev
mailing list