[FFmpeg-devel] [PATCH] Fix a bug in ff_thread_report_progress in updating progress[field].

2016-02-29 Thread Wan-Teh Chang
This bug was found by Dmitry Vyukov. If two threads may call
ff_thread_report_progress at the same time, progress[field] may
decrease. For example, suppose progress[field] is 10 and two threads
call ff_thread_report_progress to update progress[field] to 11 and
12, respectively. If the second thread acquires progress_mutex first
and updates progress[field] to 12, then the first thread will update
progress[field] to 11, causing progress[field] to decrease.
---
 libavcodec/pthread_frame.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
index b77dd1e..a43e8fe 100644
--- a/libavcodec/pthread_frame.c
+++ b/libavcodec/pthread_frame.c
@@ -482,8 +482,10 @@ void ff_thread_report_progress(ThreadFrame *f, int n, int 
field)
 av_log(f->owner, AV_LOG_DEBUG, "%p finished %d field %d\n", progress, 
n, field);
 
 pthread_mutex_lock(&p->progress_mutex);
-progress[field] = n;
-pthread_cond_broadcast(&p->progress_cond);
+if (progress[field] < n) {
+progress[field] = n;
+pthread_cond_broadcast(&p->progress_cond);
+}
 pthread_mutex_unlock(&p->progress_mutex);
 }
 
-- 
2.7.0.rc3.207.g0ac5344

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] Fix a bug in ff_thread_report_progress in updating progress[field].

2016-02-29 Thread Ronald S. Bultje
Hi,

On Mon, Feb 29, 2016 at 5:41 PM, Wan-Teh Chang  wrote:

> This bug was found by Dmitry Vyukov. If two threads may call
> ff_thread_report_progress at the same time, progress[field] may
> decrease. For example, suppose progress[field] is 10 and two threads
> call ff_thread_report_progress to update progress[field] to 11 and
> 12, respectively. If the second thread acquires progress_mutex first
> and updates progress[field] to 12, then the first thread will update
> progress[field] to 11, causing progress[field] to decrease.
> ---
>  libavcodec/pthread_frame.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
> index b77dd1e..a43e8fe 100644
> --- a/libavcodec/pthread_frame.c
> +++ b/libavcodec/pthread_frame.c
> @@ -482,8 +482,10 @@ void ff_thread_report_progress(ThreadFrame *f, int n,
> int field)
>  av_log(f->owner, AV_LOG_DEBUG, "%p finished %d field %d\n",
> progress, n, field);
>
>  pthread_mutex_lock(&p->progress_mutex);
> -progress[field] = n;
> -pthread_cond_broadcast(&p->progress_cond);
> +if (progress[field] < n) {
> +progress[field] = n;
> +pthread_cond_broadcast(&p->progress_cond);
> +}
>  pthread_mutex_unlock(&p->progress_mutex);
>  }


Do you have a sample+commandline to reproduce? The thing is, in all cases
where we use this, only one thread writes to a specific progress[n]. Two
threads may write to progress[], one per field, but one will write to
progress[0] and the other to progress[1]. If this happens, I don't mind the
patch, but I'd like to know how exactly this happens (also for posterity
documentation purposes).

Ronald
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] Fix a bug in ff_thread_report_progress in updating progress[field].

2016-03-01 Thread Wan-Teh Chang
On Mon, Feb 29, 2016 at 7:00 PM, Ronald S. Bultje  wrote:
>
> Do you have a sample+commandline to reproduce? The thing is, in all cases
> where we use this, only one thread writes to a specific progress[n]. Two
> threads may write to progress[], one per field, but one will write to
> progress[0] and the other to progress[1]. If this happens, I don't mind the
> patch, but I'd like to know how exactly this happens (also for posterity
> documentation purposes).

Dmitry Vyukov found this issue by code inspection. We understand this
is a bug only if two threads may call ff_thread_report_progress, on
the same progress[field] value (which I didn't state in my original
report), at the same time. I thought we should report the issue here
to get your opinion.

You can reject this patch, or accept the patch to make it easier to
reason about the correctness of the code.

By the way, I'm also wondering why ff_thread_report_progress is
sometimes called with progress[field] >= n? I saw it happen when I ran
make fate-h264, but did not investigate it.

Thanks,
Wan-Teh Chang
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] Fix a bug in ff_thread_report_progress in updating progress[field].

2016-03-01 Thread Ronald S. Bultje
Hi,

On Tue, Mar 1, 2016 at 9:34 AM, Wan-Teh Chang 
wrote:

> By the way, I'm also wondering why ff_thread_report_progress is
> sometimes called with progress[field] >= n? I saw it happen when I ran
> make fate-h264, but did not investigate it.


I don't know, which sample (test name) specifically?

Ronald
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] Fix a bug in ff_thread_report_progress in updating progress[field].

2016-03-01 Thread Wan-Teh Chang
On Tue, Mar 1, 2016 at 7:44 AM, Ronald S. Bultje  wrote:
> Hi,
>
> On Tue, Mar 1, 2016 at 9:34 AM, Wan-Teh Chang 
> wrote:
>
>> By the way, I'm also wondering why ff_thread_report_progress is
>> sometimes called with progress[field] >= n? I saw it happen when I ran
>> make fate-h264, but did not investigate it.
>
> I don't know, which sample (test name) specifically?

The attached ff_thread_report_progress.txt file is a patch for ffmpeg
that counts the fast and slow code paths in ff_thread_report_progress
and ff_thread_await_progress, and prints the counters at the end.

I ran "make fate-h264 THREADS=4". Here are the results, which show
that the fast code path (progress[field] >= n) was taken in
ff_thread_report_progress.

wtc@hostname:~/ffmpeg-dev/fast-slow-paths-instrumentation/ffmpeg/tests/data/fate$
grep slow *.err
h264-conformance-aud_mw_e.err:report_progress: fast=100, slow=1000 |
await_progress: fast=10999, slow=198
h264-conformance-ba1_ft_c.err:report_progress: fast=299, slow=5382 |
await_progress: fast=112159, slow=1254
h264-conformance-ba1_sony_d.err:report_progress: fast=17, slow=153 |
await_progress: fast=0, slow=0
h264-conformance-ba2_sony_f.err:report_progress: fast=300, slow=2700 |
await_progress: fast=36259, slow=688
h264-conformance-ba3_sva_c.err:report_progress: fast=17, slow=153 |
await_progress: fast=6054, slow=48
h264-conformance-bamq1_jvc_c.err:report_progress: fast=30, slow=270 |
await_progress: fast=0, slow=0
h264-conformance-bamq2_jvc_c.err:report_progress: fast=30, slow=270 |
await_progress: fast=4235, slow=87
h264-conformance-ba_mw_d.err:report_progress: fast=100, slow=900 |
await_progress: fast=10969, slow=223
h264-conformance-banm_mw_d.err:report_progress: fast=100, slow=900 |
await_progress: fast=9003, slow=243
h264-conformance-basqp1_sony_c.err:report_progress: fast=4, slow=36 |
await_progress: fast=0, slow=0
h264-conformance-caba1_sony_d.err:report_progress: fast=50, slow=450 |
await_progress: fast=0, slow=0
h264-conformance-caba1_sva_b.err:report_progress: fast=17, slow=153 |
await_progress: fast=0, slow=0
h264-conformance-caba2_sony_e.err:report_progress: fast=300, slow=2700
| await_progress: fast=34215, slow=920
h264-conformance-caba2_sva_b.err:report_progress: fast=17, slow=153 |
await_progress: fast=1610, slow=24
h264-conformance-caba3_sony_c.err:report_progress: fast=101, slow=909
| await_progress: fast=60774, slow=264
h264-conformance-caba3_sva_b.err:report_progress: fast=17, slow=153 |
await_progress: fast=6637, slow=91
h264-conformance-caba3_toshiba_e.err:report_progress: fast=300,
slow=2700 | await_progress: fast=28113, slow=716
h264-conformance-cabaci3_sony_b.err:report_progress: fast=101,
slow=909 | await_progress: fast=60989, slow=302
h264-conformance-cabac_mot_fld0_full.err:report_progress: fast=24,
slow=360 | await_progress: fast=72775, slow=83
h264-conformance-cabac_mot_frm0_full.err:report_progress: fast=12,
slow=360 | await_progress: fast=79299, slow=225
h264-conformance-cabac_mot_mbaff0_full.err:report_progress: fast=12,
slow=180 | await_progress: fast=77371, slow=119
h264-conformance-cabac_mot_picaff0_full.err:report_progress: fast=18,
slow=346 | await_progress: fast=88910, slow=169
h264-conformance-cabast3_sony_e.err:report_progress: fast=9, slow=162
| await_progress: fast=7851, slow=54
h264-conformance-cabastbr3_sony_b.err:report_progress: fast=25,
slow=450 | await_progress: fast=7967, slow=119
h264-conformance-cabref3_sand_d.err:report_progress: fast=36, slow=324
| await_progress: fast=38201, slow=43
h264-conformance-cacqp3_sony_d.err:report_progress: fast=26, slow=234
| await_progress: fast=9512, slow=126
h264-conformance-cafi1_sva_c.err:report_progress: fast=34, slow=510 |
await_progress: fast=78904, slow=2
h264-conformance-cama1_sony_c.err:report_progress: fast=5, slow=75 |
await_progress: fast=0, slow=0
h264-conformance-cama1_toshiba_b.err:report_progress: fast=30,
slow=270 | await_progress: fast=72871, slow=191
h264-conformance-cama1_vtc_c.err:report_progress: fast=3, slow=45 |
await_progress: fast=9041, slow=14
h264-conformance-cama2_vtc_b.err:report_progress: fast=3, slow=57 |
await_progress: fast=13790, slow=14
h264-conformance-cama3_sand_e.err:report_progress: fast=18, slow=162 |
await_progress: fast=34497, slow=77
h264-conformance-cama3_vtc_b.err:report_progress: fast=3, slow=54 |
await_progress: fast=13784, slow=13
h264-conformance-camaci3_sony_c.err:report_progress: fast=7, slow=28 |
await_progress: fast=1327, slow=22
h264-conformance-camanl1_toshiba_b.err:report_progress: fast=30,
slow=300 | await_progress: fast=71845, slow=200
h264-conformance-camanl2_toshiba_b.err:report_progress: fast=30,
slow=300 | await_progress: fast=65382, slow=187
h264-conformance-camanl3_sand_e.err:report_progress: fast=18, slow=180
| await_progress: fast=34512, slow=61
h264-conformance-camasl3_sony_b.err:report_progress: fast=7, slow=28 |
await_progress: fast=3142, slow=23
h264-conformance-camp_mot_mbaff_l30.err:report_progress: fast=12,
slow=180 | await_progress

Re: [FFmpeg-devel] [PATCH] Fix a bug in ff_thread_report_progress in updating progress[field].

2016-03-02 Thread Ronald S. Bultje
Hi,

On Tue, Mar 1, 2016 at 8:05 PM, Wan-Teh Chang 
wrote:

> On Tue, Mar 1, 2016 at 7:44 AM, Ronald S. Bultje 
> wrote:
> > Hi,
> >
> > On Tue, Mar 1, 2016 at 9:34 AM, Wan-Teh Chang <
> wtc-at-google@ffmpeg.org>
> > wrote:
> >
> >> By the way, I'm also wondering why ff_thread_report_progress is
> >> sometimes called with progress[field] >= n? I saw it happen when I ran
> >> make fate-h264, but did not investigate it.
> >
> > I don't know, which sample (test name) specifically?
>
> The attached ff_thread_report_progress.txt file is a patch for ffmpeg
> that counts the fast and slow code paths in ff_thread_report_progress
> and ff_thread_await_progress, and prints the counters at the end.
>
> I ran "make fate-h264 THREADS=4". Here are the results, which show
> that the fast code path (progress[field] >= n) was taken in
> ff_thread_report_progress.


I think I mis-read the question. We don't care if progress[field] == n,
that's a logical thing that can happen in many cases. We care only if
progress[field] > n, which would be an actual race. It's only logical that
the fast code path is taken if progress[field] == n, and this can happen
for all sort of reasons, none of which are pathological or worth spending
time on.

Ronald
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel