Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWan-Teh Chang <wtc-at-google.com@ffmpeg.org>2016-12-07 05:16:13 +0300
committerMichael Niedermayer <michael@niedermayer.cc>2016-12-13 02:07:20 +0300
commitfed50c4304eecb352e29ce789cdb96ea84d6162f (patch)
tree2514d8429a6926deb5a056b7417a747c0431c7d1 /libavutil/cpu.c
parent4cf3def805cf522ddd9c24c24ef1246b008bac2c (diff)
avutil: fix data race in av_get_cpu_flags()
Make the one-time initialization in av_get_cpu_flags() thread-safe. The static variable |cpu_flags| in libavutil/cpu.c is read and written using normal load and store operations. These are considered as data races. The fix is to use atomic load and store operations. The fix can be verified by running the libavutil/tests/cpu_init.c test program under ThreadSanitizer: ./configure --toolchain=clang-tsan make libavutil/tests/cpu_init libavutil/tests/cpu_init There should be no warnings from ThreadSanitizer. Co-author: Dmitry Vyukov of Google, who suggested the data race fix. Signed-off-by: Wan-Teh Chang <wtc@google.com> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavutil/cpu.c')
-rw-r--r--libavutil/cpu.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/libavutil/cpu.c b/libavutil/cpu.c
index 73317c4d4c..16e0c9278f 100644
--- a/libavutil/cpu.c
+++ b/libavutil/cpu.c
@@ -17,6 +17,7 @@
*/
#include <stdint.h>
+#include <stdatomic.h>
#include "cpu.h"
#include "cpu_internal.h"
@@ -44,7 +45,7 @@
#include <unistd.h>
#endif
-static int cpu_flags = -1;
+static atomic_int cpu_flags = ATOMIC_VAR_INIT(-1);
static int get_cpu_flags(void)
{
@@ -82,22 +83,23 @@ void av_force_cpu_flags(int arg){
arg |= AV_CPU_FLAG_MMX;
}
- cpu_flags = arg;
+ atomic_store_explicit(&cpu_flags, arg, memory_order_relaxed);
}
int av_get_cpu_flags(void)
{
- int flags = cpu_flags;
+ int flags = atomic_load_explicit(&cpu_flags, memory_order_relaxed);
if (flags == -1) {
flags = get_cpu_flags();
- cpu_flags = flags;
+ atomic_store_explicit(&cpu_flags, flags, memory_order_relaxed);
}
return flags;
}
void av_set_cpu_flags_mask(int mask)
{
- cpu_flags = get_cpu_flags() & mask;
+ atomic_store_explicit(&cpu_flags, get_cpu_flags() & mask,
+ memory_order_relaxed);
}
int av_parse_cpu_flags(const char *s)