[FFmpeg-devel] [PATCH] lavc/utils: remove unnecessary locking
Aaron Levinson
alevinsn_dev at levland.net
Tue Dec 12 01:25:15 EET 2017
On 12/8/2017 2:27 AM, Michael Niedermayer wrote:
> On Fri, Dec 08, 2017 at 09:49:25AM +0100, Hendrik Leppkes wrote:
>> On Fri, Dec 8, 2017 at 6:09 AM, Rostislav Pehlivanov
>> <atomnuker at gmail.com> wrote:
>>> Its already done by lockmgr.
>>>
>>> Signed-off-by: Rostislav Pehlivanov <atomnuker at gmail.com>
>>> ---
>>> libavcodec/utils.c | 6 ------
>>> 1 file changed, 6 deletions(-)
>>>
>>> diff --git a/libavcodec/utils.c b/libavcodec/utils.c
>>> index baf09119fe..796d24dcbb 100644
>>> --- a/libavcodec/utils.c
>>> +++ b/libavcodec/utils.c
>>> @@ -115,7 +115,6 @@ static int (*lockmgr_cb)(void **mutex, enum AVLockOp op) = NULL;
>>> #endif
>>>
>>>
>>> -static atomic_bool ff_avcodec_locked;
>>> static atomic_int entangled_thread_counter = ATOMIC_VAR_INIT(0);
>>> static void *codec_mutex;
>>> static void *avformat_mutex;
>>> @@ -1943,7 +1942,6 @@ int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op))
>>>
>>> int ff_lock_avcodec(AVCodecContext *log_ctx, const AVCodec *codec)
>>> {
>>> - _Bool exp = 0;
>>> if (codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE || !codec->init)
>>> return 0;
>>>
>>> @@ -1959,21 +1957,17 @@ int ff_lock_avcodec(AVCodecContext *log_ctx, const AVCodec *codec)
>>> atomic_load(&entangled_thread_counter));
>>> if (!lockmgr_cb)
>>> av_log(log_ctx, AV_LOG_ERROR, "No lock manager is set, please see av_lockmgr_register()\n");
>>> - atomic_store(&ff_avcodec_locked, 1);
>>> ff_unlock_avcodec(codec);
>>> return AVERROR(EINVAL);
>>> }
>>> - av_assert0(atomic_compare_exchange_strong(&ff_avcodec_locked, &exp, 1));
>>> return 0;
>>> }
>>>
>>> int ff_unlock_avcodec(const AVCodec *codec)
>>> {
>>> - _Bool exp = 1;
>>> if (codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE || !codec->init)
>>> return 0;
>>>
>>> - av_assert0(atomic_compare_exchange_strong(&ff_avcodec_locked, &exp, 0));
>>> atomic_fetch_add(&entangled_thread_counter, -1);
>>> if (lockmgr_cb) {
>>> if ((*lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE))
>>> --
>>> 2.15.1.424.g9478a66081
>>>
>>
>> These variables never performed any locking, they only existed as a
>> sanity check that lock/unlock is always called in pairs. If that is
>> really required is up for discussion.
>
> They shuld be usefull to detect some bugs related to locking
>
> [...]
I don't have the most recent response to this e-mail, from Hendrik, in
my inbox anymore, but I spent some time reviewing the patch, and I also
don't see any point to making access to ff_avcodec_locked atomic.
Prior to patch
https://github.com/FFmpeg/FFmpeg/commit/590136e78da3d091ea99ab5432543d47a559a461
, ff_avcodec_locked was declared as volatile and also specified as an
extern in internal.h. Neither the volatile declaration nor the global
exposure of ff_avcodec_locked are necessary. The patch eliminated the
global exposure, but it replaced "volatile" with "atomic".
Write access to ff_avcodec_locked is already protected via lockmgr_cb.
If, somehow, lockmgr_cb is NULL, which shouldn't happen in practice, the
entangled_thread_counter backup approach that immediately follows isn't
sufficient as currently implemented to protect writes to
ff_avcodec_locked, which makes me wonder why it is there in the first
place. It is possible to use entangled_thread_counter in a way that
protects access to ff_avcodec_locked though, and I think that's the
intention of the code.
I think the correct approach is to mostly restore the code prior to
patch
https://github.com/FFmpeg/FFmpeg/commit/590136e78da3d091ea99ab5432543d47a559a461
but to leave ff_avcodec_locked statically declared and eliminate the
volatile designation.
On a separate note, this whole approach of using
ff_lock_avcodec/ff_unlock_avcodec seems a little hokey to me. It is
effectively using a global lock (via lockmgr_cb) to control access to
avctx, which should be local to the calling thread. As implemented, it
prevents two concurrent calls to avcodec_open2() from proceeding
simultaneously. As far as I can tell, the implementation of
avcodec_open2() doesn't modify any global structures and only modifies
avctx. I would think that a better approach would be to use a lock that
is specific to the avctx object, perhaps one stored in avctx->internal.
This approach would also eliminate the codec_mutex memory leak.
Aaron Levinson
More information about the ffmpeg-devel
mailing list