[FFmpeg-devel] [PATCH v3 2/3] libavcodec/utils.c: simplify avcodec locking with atomics
Rostislav Pehlivanov
atomnuker at gmail.com
Sat Nov 25 21:48:13 EET 2017
On 25 November 2017 at 18:40, James Almer <jamrial at gmail.com> wrote:
> On 11/25/2017 2:01 PM, Rostislav Pehlivanov wrote:
> > Also makes it more robust than using volatiles.
> >
> > Signed-off-by: Rostislav Pehlivanov <atomnuker at gmail.com>
> > ---
> > libavcodec/internal.h | 1 -
> > libavcodec/utils.c | 12 ++++++------
> > 2 files changed, 6 insertions(+), 7 deletions(-)
> >
> > diff --git a/libavcodec/internal.h b/libavcodec/internal.h
> > index d3310b6afe..1c54966f37 100644
> > --- a/libavcodec/internal.h
> > +++ b/libavcodec/internal.h
> > @@ -246,7 +246,6 @@ int ff_init_buffer_info(AVCodecContext *s, AVFrame
> *frame);
> >
> > void ff_color_frame(AVFrame *frame, const int color[4]);
> >
> > -extern volatile int ff_avcodec_locked;
> > int ff_lock_avcodec(AVCodecContext *log_ctx, const AVCodec *codec);
> > int ff_unlock_avcodec(const AVCodec *codec);
> >
> > diff --git a/libavcodec/utils.c b/libavcodec/utils.c
> > index 3a0f3c11f5..96bc9ff4a4 100644
> > --- a/libavcodec/utils.c
> > +++ b/libavcodec/utils.c
> > @@ -114,7 +114,7 @@ static int (*lockmgr_cb)(void **mutex, enum AVLockOp
> op) = NULL;
> > #endif
> >
> >
> > -volatile int ff_avcodec_locked;
> > +static atomic_bool ff_avcodec_locked;
> > static atomic_int entangled_thread_counter = ATOMIC_VAR_INIT(0);
> > static void *codec_mutex;
> > static void *avformat_mutex;
> > @@ -1937,6 +1937,7 @@ int av_lockmgr_register(int (*cb)(void **mutex,
> enum AVLockOp op))
> >
> > int ff_lock_avcodec(AVCodecContext *log_ctx, const AVCodec *codec)
> > {
> > + _Bool exp = 1;
> > if (codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE ||
> !codec->init)
> > return 0;
> >
> > @@ -1952,22 +1953,21 @@ 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");
> > - ff_avcodec_locked = 1;
> > + atomic_store(&ff_avcodec_locked, 1);
> > ff_unlock_avcodec(codec);
> > return AVERROR(EINVAL);
> > }
> > - av_assert0(!ff_avcodec_locked);
> > - ff_avcodec_locked = 1;
> > + av_assert0(atomic_compare_exchange_strong(&ff_avcodec_locked,
> &exp, 1));
>
> _Bool atomic_compare_exchange_strong( volatile A* obj,
> C* expected, C desired );
>
> "Atomically compares the value pointed to by obj with the value pointed
> to by expected, and if those are equal, replaces the former with desired
> (performs read-modify-write operation).
> Return value: The result of the comparison: true if *obj was equal to
> *exp, false otherwise."
>
> exp should be 0. You need to assert that ff_avcodec_locked == 0, then
> set it to 1.
>
The whole experssion seems fine to me as-is and works as expected.
>
> > return 0;
> > }
> >
> > int ff_unlock_avcodec(const AVCodec *codec)
> > {
> > + _Bool exp = 0;
> > if (codec->caps_internal & FF_CODEC_CAP_INIT_THREADSAFE ||
> !codec->init)
> > return 0;
> >
> > - av_assert0(ff_avcodec_locked);
> > - ff_avcodec_locked = 0;
> > + av_assert0(atomic_compare_exchange_strong(&ff_avcodec_locked,
> &exp, 0));
>
> And here exp should be 1.
>
> > atomic_fetch_add(&entangled_thread_counter, -1);
> > if (lockmgr_cb) {
> > if ((*lockmgr_cb)(&codec_mutex, AV_LOCK_RELEASE))
> >
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
Seems like I sent an older version of the patch (had to rebase to fix older
commit), attached patch fixed both.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-libavcodec-utils.c-simplify-avcodec-locking-with-ato.patch
Type: text/x-patch
Size: 2698 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20171125/c1c7aa3f/attachment.bin>
More information about the ffmpeg-devel
mailing list