mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-21 10:55:51 +02:00
avcodec/pthread_frame: Move (init|free)_pthread() to pthread.c
We have more mutexes/condition variables whose initialization is unchecked. Also use a proper namespace for these functions. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
parent
bd95f2f599
commit
a4f7fabc26
@ -29,6 +29,8 @@
|
||||
* @see doc/multithreading.txt
|
||||
*/
|
||||
|
||||
#include "libavutil/thread.h"
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "internal.h"
|
||||
#include "pthread_internal.h"
|
||||
@ -86,3 +88,39 @@ void ff_thread_free(AVCodecContext *avctx)
|
||||
else
|
||||
ff_slice_thread_free(avctx);
|
||||
}
|
||||
|
||||
av_cold void ff_pthread_free(void *obj, const unsigned offsets[])
|
||||
{
|
||||
unsigned cnt = *(unsigned*)((char*)obj + offsets[0]);
|
||||
const unsigned *cur_offset = offsets;
|
||||
|
||||
*(unsigned*)((char*)obj + offsets[0]) = 0;
|
||||
|
||||
for (; *(++cur_offset) != THREAD_SENTINEL && cnt; cnt--)
|
||||
pthread_mutex_destroy((pthread_mutex_t*)((char*)obj + *cur_offset));
|
||||
for (; *(++cur_offset) != THREAD_SENTINEL && cnt; cnt--)
|
||||
pthread_cond_destroy ((pthread_cond_t *)((char*)obj + *cur_offset));
|
||||
}
|
||||
|
||||
av_cold int ff_pthread_init(void *obj, const unsigned offsets[])
|
||||
{
|
||||
const unsigned *cur_offset = offsets;
|
||||
unsigned cnt = 0;
|
||||
int err;
|
||||
|
||||
#define PTHREAD_INIT_LOOP(type) \
|
||||
for (; *(++cur_offset) != THREAD_SENTINEL; cnt++) { \
|
||||
pthread_ ## type ## _t *dst = (void*)((char*)obj + *cur_offset); \
|
||||
err = pthread_ ## type ## _init(dst, NULL); \
|
||||
if (err) { \
|
||||
err = AVERROR(err); \
|
||||
goto fail; \
|
||||
} \
|
||||
}
|
||||
PTHREAD_INIT_LOOP(mutex)
|
||||
PTHREAD_INIT_LOOP(cond)
|
||||
|
||||
fail:
|
||||
*(unsigned*)((char*)obj + offsets[0]) = cnt;
|
||||
return err;
|
||||
}
|
||||
|
@ -680,59 +680,18 @@ static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count
|
||||
async_lock(fctx);
|
||||
}
|
||||
|
||||
#define SENTINEL 0 // This forbids putting a mutex/condition variable at the front.
|
||||
#define OFFSET_ARRAY(...) __VA_ARGS__, SENTINEL
|
||||
#define DEFINE_OFFSET_ARRAY(type, name, mutexes, conds) \
|
||||
static const unsigned name ## _offsets[] = { offsetof(type, pthread_init_cnt),\
|
||||
OFFSET_ARRAY mutexes, \
|
||||
OFFSET_ARRAY conds }
|
||||
|
||||
#define OFF(member) offsetof(FrameThreadContext, member)
|
||||
DEFINE_OFFSET_ARRAY(FrameThreadContext, thread_ctx,
|
||||
DEFINE_OFFSET_ARRAY(FrameThreadContext, thread_ctx, pthread_init_cnt,
|
||||
(OFF(buffer_mutex), OFF(hwaccel_mutex), OFF(async_mutex)),
|
||||
(OFF(async_cond)));
|
||||
#undef OFF
|
||||
|
||||
#define OFF(member) offsetof(PerThreadContext, member)
|
||||
DEFINE_OFFSET_ARRAY(PerThreadContext, per_thread,
|
||||
DEFINE_OFFSET_ARRAY(PerThreadContext, per_thread, pthread_init_cnt,
|
||||
(OFF(progress_mutex), OFF(mutex)),
|
||||
(OFF(input_cond), OFF(progress_cond), OFF(output_cond)));
|
||||
#undef OFF
|
||||
|
||||
static av_cold void free_pthread(void *obj, const unsigned offsets[])
|
||||
{
|
||||
unsigned cnt = *(unsigned*)((char*)obj + offsets[0]);
|
||||
const unsigned *cur_offset = offsets;
|
||||
|
||||
for (; *(++cur_offset) != SENTINEL && cnt; cnt--)
|
||||
pthread_mutex_destroy((pthread_mutex_t*)((char*)obj + *cur_offset));
|
||||
for (; *(++cur_offset) != SENTINEL && cnt; cnt--)
|
||||
pthread_cond_destroy ((pthread_cond_t *)((char*)obj + *cur_offset));
|
||||
}
|
||||
|
||||
static av_cold int init_pthread(void *obj, const unsigned offsets[])
|
||||
{
|
||||
const unsigned *cur_offset = offsets;
|
||||
unsigned cnt = 0;
|
||||
int err;
|
||||
|
||||
#define PTHREAD_INIT_LOOP(type) \
|
||||
for (; *(++cur_offset) != SENTINEL; cnt++) { \
|
||||
pthread_ ## type ## _t *dst = (void*)((char*)obj + *cur_offset); \
|
||||
err = pthread_ ## type ## _init(dst, NULL); \
|
||||
if (err) { \
|
||||
err = AVERROR(err); \
|
||||
goto fail; \
|
||||
} \
|
||||
}
|
||||
PTHREAD_INIT_LOOP(mutex)
|
||||
PTHREAD_INIT_LOOP(cond)
|
||||
|
||||
fail:
|
||||
*(unsigned*)((char*)obj + offsets[0]) = cnt;
|
||||
return err;
|
||||
}
|
||||
|
||||
void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
|
||||
{
|
||||
FrameThreadContext *fctx = avctx->internal->thread_ctx;
|
||||
@ -792,14 +751,14 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
|
||||
|
||||
av_frame_free(&p->frame);
|
||||
|
||||
free_pthread(p, per_thread_offsets);
|
||||
ff_pthread_free(p, per_thread_offsets);
|
||||
av_packet_free(&p->avpkt);
|
||||
|
||||
av_freep(&p->avctx);
|
||||
}
|
||||
|
||||
av_freep(&fctx->threads);
|
||||
free_pthread(fctx, thread_ctx_offsets);
|
||||
ff_pthread_free(fctx, thread_ctx_offsets);
|
||||
|
||||
av_freep(&avctx->internal->thread_ctx);
|
||||
}
|
||||
@ -845,7 +804,7 @@ static av_cold int init_thread(PerThreadContext *p, int *threads_to_free,
|
||||
}
|
||||
}
|
||||
|
||||
err = init_pthread(p, per_thread_offsets);
|
||||
err = ff_pthread_init(p, per_thread_offsets);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
@ -906,9 +865,9 @@ int ff_frame_thread_init(AVCodecContext *avctx)
|
||||
if (!fctx)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
err = init_pthread(fctx, thread_ctx_offsets);
|
||||
err = ff_pthread_init(fctx, thread_ctx_offsets);
|
||||
if (err < 0) {
|
||||
free_pthread(fctx, thread_ctx_offsets);
|
||||
ff_pthread_free(fctx, thread_ctx_offsets);
|
||||
av_freep(&avctx->internal->thread_ctx);
|
||||
return err;
|
||||
}
|
||||
|
@ -31,4 +31,36 @@ void ff_slice_thread_free(AVCodecContext *avctx);
|
||||
int ff_frame_thread_init(AVCodecContext *avctx);
|
||||
void ff_frame_thread_free(AVCodecContext *avctx, int thread_count);
|
||||
|
||||
#define THREAD_SENTINEL 0 // This forbids putting a mutex/condition variable at the front.
|
||||
/**
|
||||
* Initialize/destroy a list of mutexes/conditions contained in a structure.
|
||||
* The positions of these mutexes/conditions in the structure are given by
|
||||
* their offsets. Because it is undefined behaviour to destroy
|
||||
* an uninitialized mutex/condition, ff_pthread_init() stores the number
|
||||
* of successfully initialized mutexes and conditions in the object itself
|
||||
* and ff_pthread_free() uses this number to destroy exactly the mutexes and
|
||||
* condition variables that have been successfully initialized.
|
||||
*
|
||||
* @param obj The object containing the mutexes/conditions.
|
||||
* @param[in] offsets An array of offsets. Its first member gives the offset
|
||||
* of the variable that contains the count of successfully
|
||||
* initialized mutexes/condition variables; said variable
|
||||
* must be an unsigned int. Two arrays of offsets, each
|
||||
* delimited by a THREAD_SENTINEL follow. The first
|
||||
* contains the offsets of all the mutexes, the second
|
||||
* contains the offsets of all the condition variables.
|
||||
*/
|
||||
int ff_pthread_init(void *obj, const unsigned offsets[]);
|
||||
void ff_pthread_free(void *obj, const unsigned offsets[]);
|
||||
|
||||
/**
|
||||
* Macros to help creating the above lists. mutexes and conds need
|
||||
* to be parentheses-enclosed lists of offsets in the containing structure.
|
||||
*/
|
||||
#define OFFSET_ARRAY(...) __VA_ARGS__, THREAD_SENTINEL
|
||||
#define DEFINE_OFFSET_ARRAY(type, name, cnt_variable, mutexes, conds) \
|
||||
static const unsigned name ## _offsets[] = { offsetof(type, cnt_variable), \
|
||||
OFFSET_ARRAY mutexes, \
|
||||
OFFSET_ARRAY conds }
|
||||
|
||||
#endif // AVCODEC_PTHREAD_INTERNAL_H
|
||||
|
Loading…
Reference in New Issue
Block a user