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),
107 nb_threads = nb_cpus + 1;
112 nb_workers = nb_threads;
120 if (nb_workers && !(
ctx->workers =
av_calloc(nb_workers,
sizeof(*
ctx->workers)))) {
128 ctx->nb_threads = nb_threads;
129 ctx->nb_active_threads = 0;
149 for (
i = 0;
i < nb_workers;
i++) {
150 WorkerContext *
w = &
ctx->workers[
i];
188 int nb_workers,
i, is_last = 0;
191 ctx->nb_jobs = nb_jobs;
192 ctx->nb_active_threads =
FFMIN(nb_jobs,
ctx->nb_threads);
195 nb_workers =
ctx->nb_active_threads;
196 if (!
ctx->main_func || !execute_main)
199 for (
i = 0;
i < nb_workers;
i++) {
200 WorkerContext *
w = &
ctx->workers[
i];
207 if (
ctx->main_func && execute_main)
208 ctx->main_func(
ctx->priv);
210 is_last = run_jobs(
ctx);
230 nb_workers =
ctx->nb_threads;
235 for (
i = 0;
i < nb_workers;
i++) {
236 WorkerContext *
w = &
ctx->workers[
i];
243 for (
i = 0;
i < nb_workers;
i++) {
244 WorkerContext *
w = &
ctx->workers[
i];
259 void (*
worker_func)(
void *priv,
int jobnr,
int threadnr,
int nb_jobs,
int nb_threads),
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
#define atomic_fetch_add_explicit(object, operand, order)
#define atomic_store_explicit(object, desired, order)
#define atomic_init(obj, value)
#define pthread_mutex_lock(a)
#define pthread_mutex_unlock(a)
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
#define attribute_align_arg
Memory handling functions.
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
static av_always_inline int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
int(* cond)(enum AVPixelFormat pix_fmt)
static void worker_func(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads)
int() main_func(AVCodecContext *c)
typedef void(RENAME(mix_any_func_type))
void avpriv_slicethread_execute(AVSliceThread *ctx, int nb_jobs, int execute_main)
Execute slice threading.
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_free(AVSliceThread **pctx)
Destroy slice threading context.
struct AVSliceThread AVSliceThread