diff options
Diffstat (limited to 'libavfilter/pthread.c')
-rw-r--r-- | libavfilter/pthread.c | 151 |
1 files changed, 18 insertions, 133 deletions
diff --git a/libavfilter/pthread.c b/libavfilter/pthread.c index 2ebcc9753a..567dd4c178 100644 --- a/libavfilter/pthread.c +++ b/libavfilter/pthread.c @@ -1,18 +1,18 @@ /* - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -26,174 +26,59 @@ #include "libavutil/common.h" #include "libavutil/cpu.h" #include "libavutil/mem.h" +#include "libavutil/thread.h" +#include "libavutil/slicethread.h" #include "avfilter.h" #include "internal.h" #include "thread.h" -#if HAVE_PTHREADS -#include <pthread.h> -#elif HAVE_W32THREADS -#include "compat/w32pthreads.h" -#endif - 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_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 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); - - c->rets[our_job % c->nb_rets] = c->func(c->ctx, c->arg, our_job, c->nb_jobs); - - 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, void *arg, int *ret, int nb_jobs) { ThreadContext *c = ctx->graph->internal->thread; - int dummy_ret; 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; - if (ret) { - c->rets = ret; - c->nb_rets = nb_jobs; - } else { - c->rets = &dummy_ret; - c->nb_rets = 1; - } - c->current_execute++; - - pthread_cond_broadcast(&c->current_job_cond); - - slice_thread_park_workers(c); + c->rets = ret; + 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(); - av_log(c->graph, AV_LOG_DEBUG, "Detected %d logical cores.\n", nb_cpus); - // 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(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) |