From 9ab4d9df387d3dd3881fae4d7af6215f37e3c9b8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Peter=20Bostr=C3=B6m?= <pbos@google.com>
Date: Thu, 31 Aug 2017 14:33:59 -0700
Subject: [PATCH] Prevent data race from low-pass filter.

Makes main thread wait for the filter level to be picked to avoid a race
between the LPF thread and update_reference_frames(). This also
re-enables the failing tests under thread_sanitizer where this data race
was detected.

BUG=webm:1460

Change-Id: I7f5797142ea0200394309842ce3e91a480be4fbc
---
 test/datarate_test.cc | 14 --------------
 vp8/encoder/onyx_if.c | 10 +++-------
 2 files changed, 3 insertions(+), 21 deletions(-)

diff --git a/test/datarate_test.cc b/test/datarate_test.cc
index 8e93de6b9..a88f786c1 100644
--- a/test/datarate_test.cc
+++ b/test/datarate_test.cc
@@ -258,14 +258,6 @@ TEST_P(DatarateTestLarge, ChangingDropFrameThresh) {
   }
 }
 
-// Disabled for tsan, see:
-// https://bugs.chromium.org/p/webm/issues/detail?id=1049
-#if defined(__has_feature)
-#if __has_feature(thread_sanitizer)
-#define BUILDING_WITH_TSAN
-#endif
-#endif
-#ifndef BUILDING_WITH_TSAN
 TEST_P(DatarateTestLarge, DropFramesMultiThreads) {
   denoiser_on_ = 0;
   cfg_.rc_buf_initial_sz = 500;
@@ -285,7 +277,6 @@ TEST_P(DatarateTestLarge, DropFramesMultiThreads) {
   ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
       << " The datarate for the file missed the target!";
 }
-#endif  // !BUILDING_WITH_TSAN
 
 class DatarateTestRealTime : public DatarateTestLarge {
  public:
@@ -402,10 +393,6 @@ TEST_P(DatarateTestRealTime, ChangingDropFrameThresh) {
   }
 }
 
-// Disabled for tsan, see:
-// https://bugs.chromium.org/p/webm/issues/detail?id=1049
-
-#ifndef BUILDING_WITH_TSAN
 TEST_P(DatarateTestRealTime, DropFramesMultiThreads) {
   denoiser_on_ = 0;
   cfg_.rc_buf_initial_sz = 500;
@@ -426,7 +413,6 @@ TEST_P(DatarateTestRealTime, DropFramesMultiThreads) {
   ASSERT_LE(cfg_.rc_target_bitrate, file_datarate_ * 1.4)
       << " The datarate for the file missed the target!";
 }
-#endif
 
 TEST_P(DatarateTestRealTime, GFBoost) {
   denoiser_on_ = 0;
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index 725e000e2..2c2a783a9 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -4445,6 +4445,9 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, size_t *size,
     /* start loopfilter in separate thread */
     sem_post(&cpi->h_event_start_lpf);
     cpi->b_lpf_running = 1;
+    /* wait for the filter_level to be picked so that we can continue with
+     * stream packing */
+    sem_wait(&cpi->h_event_end_lpf);
   } else
 #endif
   {
@@ -4464,13 +4467,6 @@ static void encode_frame_to_data_rate(VP8_COMP *cpi, size_t *size,
   }
 #endif
 
-#if CONFIG_MULTITHREAD
-  /* wait that filter_level is picked so that we can continue with stream
-   * packing */
-  if (vpx_atomic_load_acquire(&cpi->b_multi_threaded))
-    sem_wait(&cpi->h_event_end_lpf);
-#endif
-
   /* build the bitstream */
   vp8_pack_bitstream(cpi, dest, dest_end, size);