X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Fpthread.c;h=567dd4c178c93a01cbfc4fc7f29df8a4b0b8a68c;hb=276f035a4d0f0cbd88c0b67d0358d3d121202c5a;hp=c7a00210d6648379547726344faf20852a0ce496;hpb=77a20cff3628b7353164b8433a6b4d4140c901bf;p=ffmpeg diff --git a/libavfilter/pthread.c b/libavfilter/pthread.c index c7a00210d66..567dd4c178c 100644 --- a/libavfilter/pthread.c +++ b/libavfilter/pthread.c @@ -27,6 +27,7 @@ #include "libavutil/cpu.h" #include "libavutil/mem.h" #include "libavutil/thread.h" +#include "libavutil/slicethread.h" #include "avfilter.h" #include "internal.h" @@ -34,85 +35,26 @@ typedef struct ThreadContext { AVFilterGraph *graph; - - int nb_threads; - pthread_t *workers; + AVSliceThread *thread; avfilter_action_func *func; /* per-execute parameters */ AVFilterContext *ctx; void *arg; int *rets; - int nb_jobs; - - pthread_cond_t last_job_cond; - pthread_cond_t current_job_cond; - pthread_mutex_t current_job_lock; - int current_job; - unsigned int current_execute; - int done; } ThreadContext; -static void* attribute_align_arg worker(void *v) +static void worker_func(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads) { - ThreadContext *c = v; - int our_job = c->nb_jobs; - int nb_threads = c->nb_threads; - unsigned int last_execute = 0; - int ret, self_id; - - pthread_mutex_lock(&c->current_job_lock); - self_id = c->current_job++; - - for (;;) { - while (our_job >= c->nb_jobs) { - if (c->current_job == nb_threads + c->nb_jobs) - pthread_cond_signal(&c->last_job_cond); - - while (last_execute == c->current_execute && !c->done) - pthread_cond_wait(&c->current_job_cond, &c->current_job_lock); - last_execute = c->current_execute; - our_job = self_id; - - if (c->done) { - pthread_mutex_unlock(&c->current_job_lock); - return NULL; - } - } - pthread_mutex_unlock(&c->current_job_lock); - - ret = c->func(c->ctx, c->arg, our_job, c->nb_jobs); - if (c->rets) - c->rets[our_job % c->nb_jobs] = ret; - - pthread_mutex_lock(&c->current_job_lock); - our_job = c->current_job++; - } + ThreadContext *c = priv; + int ret = c->func(c->ctx, c->arg, jobnr, nb_jobs); + if (c->rets) + c->rets[jobnr] = ret; } static void slice_thread_uninit(ThreadContext *c) { - int i; - - pthread_mutex_lock(&c->current_job_lock); - c->done = 1; - pthread_cond_broadcast(&c->current_job_cond); - pthread_mutex_unlock(&c->current_job_lock); - - for (i = 0; i < c->nb_threads; i++) - pthread_join(c->workers[i], NULL); - - pthread_mutex_destroy(&c->current_job_lock); - pthread_cond_destroy(&c->current_job_cond); - pthread_cond_destroy(&c->last_job_cond); - av_freep(&c->workers); -} - -static void slice_thread_park_workers(ThreadContext *c) -{ - while (c->current_job != c->nb_threads + c->nb_jobs) - pthread_cond_wait(&c->last_job_cond, &c->current_job_lock); - pthread_mutex_unlock(&c->current_job_lock); + avpriv_slicethread_free(&c->thread); } static int thread_execute(AVFilterContext *ctx, avfilter_action_func *func, @@ -122,67 +64,21 @@ static int thread_execute(AVFilterContext *ctx, avfilter_action_func *func, if (nb_jobs <= 0) return 0; - - pthread_mutex_lock(&c->current_job_lock); - - c->current_job = c->nb_threads; - c->nb_jobs = nb_jobs; c->ctx = ctx; c->arg = arg; c->func = func; c->rets = ret; - c->current_execute++; - - pthread_cond_broadcast(&c->current_job_cond); - - slice_thread_park_workers(c); + avpriv_slicethread_execute(c->thread, nb_jobs, 0); return 0; } static int thread_init_internal(ThreadContext *c, int nb_threads) { - int i, ret; - - if (!nb_threads) { - int nb_cpus = av_cpu_count(); - // use number of cores + 1 as thread count if there is more than one - if (nb_cpus > 1) - nb_threads = nb_cpus + 1; - else - nb_threads = 1; - } - + nb_threads = avpriv_slicethread_create(&c->thread, c, worker_func, NULL, nb_threads); if (nb_threads <= 1) - return 1; - - c->nb_threads = nb_threads; - c->workers = av_mallocz_array(sizeof(*c->workers), nb_threads); - if (!c->workers) - return AVERROR(ENOMEM); - - c->current_job = 0; - c->nb_jobs = 0; - c->done = 0; - - pthread_cond_init(&c->current_job_cond, NULL); - pthread_cond_init(&c->last_job_cond, NULL); - - pthread_mutex_init(&c->current_job_lock, NULL); - pthread_mutex_lock(&c->current_job_lock); - for (i = 0; i < nb_threads; i++) { - ret = pthread_create(&c->workers[i], NULL, worker, c); - if (ret) { - pthread_mutex_unlock(&c->current_job_lock); - c->nb_threads = i; - slice_thread_uninit(c); - return AVERROR(ret); - } - } - - slice_thread_park_workers(c); - - return c->nb_threads; + avpriv_slicethread_free(&c->thread); + return FFMAX(nb_threads, 1); } int ff_graph_thread_init(AVFilterGraph *graph)