diff mbox series

[FFmpeg-devel,221/223] avutil/cpu: Fix race condition in av_cpu_count()

Message ID 20201203003628.778278-4-andreas.rheinhardt@gmail.com
State Accepted
Headers show
Series [FFmpeg-devel,01/45] avcodec/a64multienc: Fix memleak upon init failure | expand

Checks

Context Check Description
andriy/x86 warning Failed to apply patch

Commit Message

Andreas Rheinhardt Dec. 3, 2020, 12:36 a.m. UTC
av_cpu_count() intends to emit a debug message containing the number of
logical cores when called the first time. The check currently works with
a static volatile int; yet this does not help at all in case of
concurrent accesses by multiple threads. So replace this with an
atomic_int.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
---
To test my patches I have modified avcodec_open2() to always open the
desired AVCodecContext simultaneously from two different threads [1].
With this one easily runs into this issue when one uses a decoder with
FF_CODEC_CAP_INIT_THREADSAFE that supports threading.

[1]: https://pastebin.com/a1uEuQ81

 libavutil/cpu.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

Comments

Andreas Rheinhardt April 2, 2021, 4:37 p.m. UTC | #1
On Thu, Dec 3, 2020 at 1:36 AM Andreas Rheinhardt <
andreas.rheinhardt@gmail.com> wrote:

> av_cpu_count() intends to emit a debug message containing the number of
> logical cores when called the first time. The check currently works with
> a static volatile int; yet this does not help at all in case of
> concurrent accesses by multiple threads. So replace this with an
> atomic_int.
>
> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
> ---
> To test my patches I have modified avcodec_open2() to always open the
> desired AVCodecContext simultaneously from two different threads [1].
> With this one easily runs into this issue when one uses a decoder with
> FF_CODEC_CAP_INIT_THREADSAFE that supports threading.
>
> [1]: https://pastebin.com/a1uEuQ81
>
>  libavutil/cpu.c | 6 ++----
>  1 file changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/libavutil/cpu.c b/libavutil/cpu.c
> index 52f6b9a3bf..7b8a9045ab 100644
> --- a/libavutil/cpu.c
> +++ b/libavutil/cpu.c
> @@ -274,7 +274,7 @@ int av_parse_cpu_caps(unsigned *flags, const char *s)
>
>  int av_cpu_count(void)
>  {
> -    static volatile int printed;
> +    static atomic_int printed = 0;
>
>      int nb_cpus = 1;
>  #if HAVE_WINRT
> @@ -306,10 +306,8 @@ int av_cpu_count(void)
>      nb_cpus = sysinfo.dwNumberOfProcessors;
>  #endif
>
> -    if (!printed) {
> +    if (!atomic_exchange_explicit(&printed, 1, memory_order_relaxed))
>          av_log(NULL, AV_LOG_DEBUG, "detected %d logical cores\n",
> nb_cpus);
> -        printed = 1;
> -    }
>
>      return nb_cpus;
>  }
> --
> 2.25.1
>
>
Will apply.

- Andreas
diff mbox series

Patch

diff --git a/libavutil/cpu.c b/libavutil/cpu.c
index 52f6b9a3bf..7b8a9045ab 100644
--- a/libavutil/cpu.c
+++ b/libavutil/cpu.c
@@ -274,7 +274,7 @@  int av_parse_cpu_caps(unsigned *flags, const char *s)
 
 int av_cpu_count(void)
 {
-    static volatile int printed;
+    static atomic_int printed = 0;
 
     int nb_cpus = 1;
 #if HAVE_WINRT
@@ -306,10 +306,8 @@  int av_cpu_count(void)
     nb_cpus = sysinfo.dwNumberOfProcessors;
 #endif
 
-    if (!printed) {
+    if (!atomic_exchange_explicit(&printed, 1, memory_order_relaxed))
         av_log(NULL, AV_LOG_DEBUG, "detected %d logical cores\n", nb_cpus);
-        printed = 1;
-    }
 
     return nb_cpus;
 }