aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2020-07-26 18:39:53 +0200
committerAnton Khirnov <anton@khirnov.net>2020-07-26 18:39:53 +0200
commit29f5b628317bcf83ddc5bfeaec92108b6bb1e89d (patch)
tree60b476d9a073045e3bc1cf5729b47174d04f7701
parente6180b82d89d69846cfdd7881dd067ff38ea6a79 (diff)
Switch to external threadpool library.
-rw-r--r--Makefile3
-rw-r--r--init.c9
-rw-r--r--nlsolve.c11
-rw-r--r--nlsolve.h5
-rw-r--r--pssolve.c17
-rw-r--r--pssolve.h5
-rw-r--r--threadpool.c178
-rw-r--r--threadpool.h32
8 files changed, 25 insertions, 235 deletions
diff --git a/Makefile b/Makefile
index 457489d..fae7da1 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
TARGET = libteukolskydata.so
CFLAGS = -std=c99 -D_XOPEN_SOURCE=700 -fPIC -g -I.
-TARGET_LDFLAGS = -Wl,--version-script=libteukolskydata.v -shared -lm -llapacke -pthread
+TARGET_LDFLAGS = -Wl,--version-script=libteukolskydata.v -shared -lm -llapacke -lthreadpool
TEST_LIBS = -lm -llapacke -lcblas -lpthread
CC = cc
@@ -14,7 +14,6 @@ OBJS = basis.o \
nlsolve.o \
pssolve.o \
td_constraints.o \
- threadpool.o \
TESTPROGS = nlsolve \
pssolve
diff --git a/init.c b/init.c
index e39d1b1..f4d130f 100644
--- a/init.c
+++ b/init.c
@@ -31,6 +31,8 @@
#include <clBLAS.h>
#endif
+#include <threadpool.h>
+
#include "basis.h"
#include "common.h"
#include "cpu.h"
@@ -38,7 +40,6 @@
#include "nlsolve.h"
#include "td_constraints.h"
#include "teukolsky_data.h"
-#include "threadpool.h"
#define NB_EQUATIONS 3
@@ -46,7 +47,7 @@ typedef struct TDPriv {
unsigned int basis_order[NB_EQUATIONS][2];
BasisSetContext *basis[NB_EQUATIONS][2];
- ThreadPoolContext *tp;
+ TPContext *tp;
TDLogger logger;
double *coeffs;
@@ -152,7 +153,7 @@ static int teukolsky_init_check_options(TDContext *td)
td->nb_threads = 1;
}
- ret = tdi_threadpool_init(&s->tp, td->nb_threads);
+ ret = tp_init(&s->tp, td->nb_threads);
if (ret < 0)
return ret;
@@ -487,7 +488,7 @@ void td_context_free(TDContext **ptd)
s = td->priv;
- tdi_threadpool_free(&s->tp);
+ tp_free(&s->tp);
#if HAVE_OPENCL
if (s->ocl_queue)
diff --git a/nlsolve.c b/nlsolve.c
index d1ab0ff..6f89e8b 100644
--- a/nlsolve.c
+++ b/nlsolve.c
@@ -34,12 +34,13 @@
#include <clBLAS.h>
#endif
+#include <threadpool.h>
+
#include "basis.h"
#include "common.h"
#include "log.h"
#include "pssolve.h"
#include "nlsolve.h"
-#include "threadpool.h"
#define NB_COEFFS(td) (td->nb_coeffs[0] * td->nb_coeffs[1])
#define NB_COLLOC_POINTS(td) (td->nb_colloc_points[0] * td->nb_colloc_points[1])
@@ -87,8 +88,8 @@ struct NLSolvePriv {
double *delta;
double *rhs;
- ThreadPoolContext *tp;
- ThreadPoolContext *tp_internal;
+ TPContext *tp;
+ TPContext *tp_internal;
uint64_t solve_count;
uint64_t solve_time;
@@ -455,7 +456,7 @@ int tdi_nlsolve_context_init(NLSolveContext *ctx)
if (ctx->tp) {
s->tp = ctx->tp;
} else {
- ret = tdi_threadpool_init(&s->tp_internal, 1);
+ ret = tp_init(&s->tp_internal, 1);
if (ret < 0)
return ret;
s->tp = s->tp_internal;
@@ -545,7 +546,7 @@ void tdi_nlsolve_context_free(NLSolveContext **pctx)
tdi_pssolve_context_free(&ctx->priv->ps_ctx);
- tdi_threadpool_free(&ctx->priv->tp_internal);
+ tp_free(&ctx->priv->tp_internal);
}
free(ctx->priv);
diff --git a/nlsolve.h b/nlsolve.h
index 426cb24..eaa2b64 100644
--- a/nlsolve.h
+++ b/nlsolve.h
@@ -19,10 +19,11 @@
#ifndef TEUKOLSKY_DATA_NLSOLVE_H
#define TEUKOLSKY_DATA_NLSOLVE_H
+#include <threadpool.h>
+
#include "basis.h"
#include "log.h"
#include "pssolve.h"
-#include "threadpool.h"
typedef struct NLSolvePriv NLSolvePriv;
@@ -43,7 +44,7 @@ typedef struct NLSolveContext {
* caller before tdi_nlsolve_context_init(), otherwise a single thread will
* be used.
*/
- ThreadPoolContext *tp;
+ TPContext *tp;
/**
* Number of equations/unknown functions in the set.
diff --git a/pssolve.c b/pssolve.c
index 28333e2..36e09cf 100644
--- a/pssolve.c
+++ b/pssolve.c
@@ -28,12 +28,12 @@
#include <cblas.h>
#include <lapacke.h>
+#include <threadpool.h>
#include "bicgstab.h"
#include "common.h"
#include "log.h"
#include "pssolve.h"
-#include "threadpool.h"
#define NB_COEFFS(eq_ctx) ((eq_ctx)->nb_coeffs[0] * (eq_ctx)->nb_coeffs[1])
#define NB_COLLOC_POINTS(eq_ctx) ((eq_ctx)->nb_colloc_points[0] * (eq_ctx)->nb_colloc_points[1])
@@ -58,8 +58,8 @@ struct PSSolvePriv {
int *ipiv;
double *mat;
- ThreadPoolContext *tp;
- ThreadPoolContext *tp_internal;
+ TPContext *tp;
+ TPContext *tp_internal;
};
typedef struct ConstructMatrixThread {
@@ -70,9 +70,7 @@ typedef struct ConstructMatrixThread {
unsigned int var_idx;
} ConstructMatrixThread;
-static void construct_matrix(void *arg,
- unsigned int job_idx, unsigned int nb_jobs,
- unsigned int thread_idx, unsigned int nb_threads)
+static void construct_matrix(void *arg, unsigned int job_idx, unsigned int thread_idx)
{
ConstructMatrixThread *cmt = arg;
const PSEquationContext *eq_ctx = cmt->eq_ctx;
@@ -192,8 +190,7 @@ int tdi_pssolve_solve(PSSolveContext *ctx,
.mat_stride = s->nb_coeffs,
.var_idx = j,
};
- tdi_threadpool_execute(s->tp, NB_COEFFS(&s->eqs[j]), construct_matrix,
- &thread);
+ tp_execute(s->tp, NB_COEFFS(&s->eqs[j]), construct_matrix, &thread);
mat += NB_COEFFS(&s->eqs[j]) * s->nb_coeffs;
}
}
@@ -347,7 +344,7 @@ int tdi_pssolve_context_init(PSSolveContext *ctx)
if (ctx->tp) {
s->tp = ctx->tp;
} else {
- ret = tdi_threadpool_init(&s->tp_internal, 1);
+ ret = tp_init(&s->tp_internal, 1);
if (ret < 0)
return ret;
s->tp = s->tp_internal;
@@ -487,7 +484,7 @@ void tdi_pssolve_context_free(PSSolveContext **pctx)
free(ctx->priv->mat);
tdi_bicgstab_context_free(&ctx->priv->bicgstab);
- tdi_threadpool_free(&ctx->priv->tp_internal);
+ tp_free(&ctx->priv->tp_internal);
}
free(ctx->priv);
diff --git a/pssolve.h b/pssolve.h
index 6d5d1c0..160e179 100644
--- a/pssolve.h
+++ b/pssolve.h
@@ -51,9 +51,10 @@ typedef void* cl_command_queue;
#include <stdint.h>
+#include <threadpool.h>
+
#include "basis.h"
#include "log.h"
-#include "threadpool.h"
enum PSSolveDiffOrder {
PSSOLVE_DIFF_ORDER_00,
@@ -122,7 +123,7 @@ typedef struct PSSolveContext {
* caller before tdi_pssolve_context_init(), otherwise a single thread will
* be used.
*/
- ThreadPoolContext *tp;
+ TPContext *tp;
cl_context ocl_ctx;
cl_command_queue ocl_queue;
diff --git a/threadpool.c b/threadpool.c
deleted file mode 100644
index ab5cf1d..0000000
--- a/threadpool.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright 2016 Anton Khirnov <anton@khirnov.net>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <errno.h>
-#include <pthread.h>
-#include <stdlib.h>
-
-#include "cpu.h"
-#include "threadpool.h"
-
-typedef struct WorkerContext {
- ThreadPoolContext *parent;
- pthread_t thread;
- unsigned int idx;
-} WorkerContext;
-
-struct ThreadPoolContext {
- WorkerContext *workers;
- unsigned int nb_workers;
-
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- void (*func)(void *arg,
- unsigned int job_idx, unsigned int nb_jobs,
- unsigned int thread_idx, unsigned int nb_threads);
- void *func_arg;
- int next_job;
- int nb_jobs;
- int nb_jobs_finished;
-
- int finish;
-};
-
-void *worker_thread(void *arg)
-{
- WorkerContext *w = arg;
- ThreadPoolContext *ctx = w->parent;
- int nb_jobs, job_idx;
-
- while (1) {
- pthread_mutex_lock(&ctx->mutex);
- while (!ctx->finish && ctx->next_job >= ctx->nb_jobs)
- pthread_cond_wait(&ctx->cond, &ctx->mutex);
-
- if (ctx->finish) {
- pthread_mutex_unlock(&ctx->mutex);
- break;
- }
-
- nb_jobs = ctx->nb_jobs;
- job_idx = ctx->next_job++;
-
- pthread_mutex_unlock(&ctx->mutex);
-
- ctx->func(ctx->func_arg, job_idx, nb_jobs, w->idx, ctx->nb_workers);
-
- pthread_mutex_lock(&ctx->mutex);
-
- ctx->nb_jobs_finished++;
-
- pthread_cond_broadcast(&ctx->cond);
- pthread_mutex_unlock(&ctx->mutex);
- }
- return NULL;
-}
-
-int tdi_threadpool_init(ThreadPoolContext **pctx, unsigned int nb_threads)
-{
- ThreadPoolContext *ctx;
- int ret = 0;
-
- if (!nb_threads) {
- nb_threads = tdi_cpu_count();
- if (!nb_threads)
- return -ENOSYS;
- }
-
- ctx = calloc(1, sizeof(*ctx));
- if (!ctx)
- return -ENOMEM;
-
- pthread_mutex_init(&ctx->mutex, NULL);
- pthread_cond_init(&ctx->cond, NULL);
-
- ctx->workers = calloc(nb_threads, sizeof(*ctx->workers));
- if (!ctx->workers) {
- ret = -ENOMEM;
- goto fail;
- }
-
- for (int i = 0; i < nb_threads; i++) {
- WorkerContext *w = &ctx->workers[i];
-
- w->idx = i;
- w->parent = ctx;
-
- ret = pthread_create(&w->thread, NULL, worker_thread, w);
- if (ret) {
- ret = -ret;
- goto fail;
- }
-
- ctx->nb_workers++;
- }
-
-
- *pctx = ctx;
- return 0;
-fail:
- tdi_threadpool_free(&ctx);
- return ret;
-}
-
-void tdi_threadpool_free(ThreadPoolContext **pctx)
-{
- ThreadPoolContext *ctx = *pctx;
-
- if (!ctx)
- return;
-
- pthread_mutex_lock(&ctx->mutex);
- ctx->finish = 1;
- pthread_cond_broadcast(&ctx->cond);
- pthread_mutex_unlock(&ctx->mutex);
-
-
- for (int i = 0; i < ctx->nb_workers; i++) {
- WorkerContext *w = &ctx->workers[i];
- pthread_join(w->thread, NULL);
- }
-
- pthread_mutex_destroy(&ctx->mutex);
- pthread_cond_destroy(&ctx->cond);
-
- free(ctx->workers);
-
- free(ctx);
- *pctx = NULL;
-}
-
-void tdi_threadpool_execute(ThreadPoolContext *ctx, unsigned int nb_jobs,
- void (*func)(void *arg,
- unsigned int job_idx, unsigned int nb_jobs,
- unsigned int thread_idx, unsigned int nb_threads),
- void *arg)
-{
- pthread_mutex_lock(&ctx->mutex);
-
- ctx->func = func;
- ctx->func_arg = arg;
-
- ctx->nb_jobs = nb_jobs;
- ctx->nb_jobs_finished = 0;
- ctx->next_job = 0;
-
- pthread_cond_broadcast(&ctx->cond);
- while (ctx->nb_jobs_finished < ctx->nb_jobs)
- pthread_cond_wait(&ctx->cond, &ctx->mutex);
-
- ctx->func = NULL;
- ctx->func_arg = NULL;
-
- pthread_mutex_unlock(&ctx->mutex);
-}
diff --git a/threadpool.h b/threadpool.h
deleted file mode 100644
index b22caab..0000000
--- a/threadpool.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2016 Anton Khirnov <anton@khirnov.net>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TEUKOLSKY_DATA_THREADPOOL_H
-#define TEUKOLSKY_DATA_THREADPOOL_H
-
-typedef struct ThreadPoolContext ThreadPoolContext;
-
-int tdi_threadpool_init(ThreadPoolContext **ctx, unsigned int nb_threads);
-void tdi_threadpool_free(ThreadPoolContext **ctx);
-
-void tdi_threadpool_execute(ThreadPoolContext *ctx, unsigned int nb_jobs,
- void (*func)(void *arg,
- unsigned int job_idx, unsigned int nb_jobs,
- unsigned int thread_idx, unsigned int nb_threads),
- void *arg);
-
-#endif /* TEUKOLSKY_DATA_THREADPOOL_H */