19 #include <stdatomic.h>    25 #if HAVE_PTHREADS || HAVE_W32THREADS || HAVE_OS2THREADS    27 typedef struct WorkerContext {
    36     WorkerContext   *workers;
    38     int             nb_active_threads;
    49     void            (*
worker_func)(
void *priv, 
int jobnr, 
int threadnr, 
int nb_jobs, 
int nb_threads);
    55     unsigned nb_jobs    = ctx->nb_jobs;
    56     unsigned nb_active_threads = ctx->nb_active_threads;
    58     unsigned current_job  = first_job;
    61         ctx->worker_func(ctx->priv, current_job, first_job, nb_jobs, nb_active_threads);
    64     return current_job == nb_jobs + nb_active_threads - 1;
    95                               void (*
worker_func)(
void *priv, 
int jobnr, 
int threadnr, 
int nb_jobs, 
int nb_threads),
   106             nb_threads = nb_cpus + 1;
   111     nb_workers = nb_threads;
   119     if (nb_workers && !(ctx->workers = 
av_calloc(nb_workers, 
sizeof(*ctx->workers)))) {
   127     ctx->nb_threads  = nb_threads;
   128     ctx->nb_active_threads = 0;
   138     for (i = 0; i < nb_workers; i++) {
   139         WorkerContext *w = &ctx->workers[i];
   166     int nb_workers, i, is_last = 0;
   169     ctx->nb_jobs           = nb_jobs;
   170     ctx->nb_active_threads = 
FFMIN(nb_jobs, ctx->nb_threads);
   173     nb_workers             = ctx->nb_active_threads;
   174     if (!ctx->main_func || !execute_main)
   177     for (i = 0; i < nb_workers; i++) {
   178         WorkerContext *w = &ctx->workers[i];
   185     if (ctx->main_func && execute_main)
   186         ctx->main_func(ctx->priv);
   188         is_last = run_jobs(ctx);
   208     nb_workers = ctx->nb_threads;
   213     for (i = 0; i < nb_workers; i++) {
   214         WorkerContext *w = &ctx->workers[i];
   221     for (i = 0; i < nb_workers; i++) {
   222         WorkerContext *w = &ctx->workers[i];
   237                               void (*
worker_func)(
void *priv, 
int jobnr, 
int threadnr, 
int nb_jobs, 
int nb_threads),
 
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
#define pthread_mutex_lock(a)
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
Memory handling functions. 
static void worker_func(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads)
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array(). 
#define av_assert0(cond)
assert() equivalent, that is always enabled. 
struct AVSliceThread AVSliceThread
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
simple assert() macros that are a bit more flexible than ISO C assert(). 
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
void avpriv_slicethread_free(AVSliceThread **pctx)
Destroy slice threading context. 
static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
#define pthread_mutex_unlock(a)
#define atomic_fetch_add_explicit(object, operand, order)
#define attribute_align_arg
static av_always_inline int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
typedef void(RENAME(mix_any_func_type))
int avpriv_slicethread_create(AVSliceThread **pctx, void *priv, void(*worker_func)(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads), void(*main_func)(void *priv), int nb_threads)
Create slice threading context. 
void avpriv_slicethread_execute(AVSliceThread *ctx, int nb_jobs, int execute_main)
Execute slice threading. 
#define atomic_store_explicit(object, desired, order)
int(* cond)(enum AVPixelFormat pix_fmt)
int() main_func(AVCodecContext *c)
static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
#define atomic_init(obj, value)