[Mesa-dev] [PATCHv3 06/16] util: allow the thread pool to be used as a singleton
Chia-I Wu
olvaffe at gmail.com
Tue Aug 19 23:40:27 PDT 2014
To have a real control over the number of driver threads, we almost never want
more than a single thread pool.
Signed-off-by: Chia-I Wu <olv at lunarg.com>
Reviewed-by: Brian Paul <brianp at vmware.com>
Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>
v2: split glsl changes to another commit
---
src/util/threadpool.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/util/threadpool.h | 9 +++++++
2 files changed, 81 insertions(+)
diff --git a/src/util/threadpool.c b/src/util/threadpool.c
index 224f411..9dc91f9 100644
--- a/src/util/threadpool.c
+++ b/src/util/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 thread pool. \p max_threads is honored only by the first
+ * call to this function.
+ */
+struct _mesa_threadpool *
+_mesa_threadpool_get_singleton(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_threadpool_wait_singleton(void)
+{
+ mtx_lock(&threadpool_lock);
+ if (threadpool)
+ _mesa_threadpool_join(threadpool, true);
+ mtx_unlock(&threadpool_lock);
+}
+
+/**
+ * Destroy the singleton thread pool.
+ */
+void
+_mesa_threadpool_destroy_singleton(void)
+{
+ mtx_lock(&threadpool_lock);
+ if (threadpool) {
+ /*
+ * No new task is allowed since this point. But whoever owns references
+ * to the pool can still complete tasks that have been queued (which
+ * will simply destroy the tasks as all tasks are marked cancelled).
+ */
+ _mesa_threadpool_set_shutdown(threadpool);
+
+ _mesa_threadpool_join(threadpool, false);
+ _mesa_threadpool_unref(threadpool);
+ threadpool = NULL;
+ }
+ mtx_unlock(&threadpool_lock);
+}
diff --git a/src/util/threadpool.h b/src/util/threadpool.h
index 48e4a47..aeda9d3 100644
--- a/src/util/threadpool.h
+++ b/src/util/threadpool.h
@@ -60,6 +60,15 @@ bool
_mesa_threadpool_complete_task(struct _mesa_threadpool *pool,
struct _mesa_threadpool_task *task);
+struct _mesa_threadpool *
+_mesa_threadpool_get_singleton(int max_threads);
+
+void
+_mesa_threadpool_wait_singleton(void);
+
+void
+_mesa_threadpool_destroy_singleton(void);
+
#ifdef __cplusplus
}
#endif
--
2.0.0.rc2
More information about the mesa-dev
mailing list