sayrer / libyuv

Automatically exported from code.google.com/p/libyuv
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

Race between TestCpuFlag and InitCpuFlags #508

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
Two concurrent initial runs of TestCpuFlag() race since cpu_info_ == kCpuInfo 
is checked/set without proper atomics.

Are we required/supposed to call libyuv::InitCpuFlags() before concurrent uses 
of libyuv to avoid undefined behavior/myriad of errors? It looks like an 
internal-only function.

Hitting this in webrtc using ThreadSanitizer. We have multiple receivers 
running concurrently, hence the race during Decode(). Repro stacks below:

Note: Google Test filter = EndToEndTest.SendsAndReceivesMultipleStreams
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from EndToEndTest
[ RUN      ] EndToEndTest.SendsAndReceivesMultipleStreams
(systeminfo.cc:82): Available number of cores: 40
==================
WARNING: ThreadSanitizer: data race (pid=11200)
  Read of size 4 at 0x0000016cae30 by thread T10 (mutexes: write M394):
    #0 libyuv::TestCpuFlag(int) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/third_party/libyuv/include/libyuv/cpu_id.h:60:11 (video_engine_tests+0x00000098920b)
    #1 CopyPlane /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/third_party/libyuv/source/planar_functions.cc:45:7 (video_engine_tests+0x0000009890d2)
    #2 I420Copy /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/third_party/libyuv/source/convert.cc:90:5 (video_engine_tests+0x0000009d1c8e)
    #3 webrtc::VP8DecoderImpl::ReturnFrame(vpx_image const*, unsigned int, long) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc:1341:3 (video_engine_tests+0x000000bd61be)
    #4 webrtc::VP8DecoderImpl::Decode(webrtc::EncodedImage const&, bool, webrtc::RTPFragmentationHeader const*, webrtc::CodecSpecificInfo const*, long) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc:1249:9 (video_engine_tests+0x000000bd5931)
    #5 webrtc::VCMGenericDecoder::Decode(webrtc::VCMEncodedFrame const&, long) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/modules/video_coding/main/source/generic_decoder.cc:154:19 (video_engine_tests+0x000000b6f958)
    #6 webrtc::vcm::VideoReceiver::Decode(webrtc::VCMEncodedFrame const&) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/modules/video_coding/main/source/video_receiver.cc:380:17 (video_engine_tests+0x000000b8abce)
    #7 webrtc::vcm::VideoReceiver::Decode(unsigned short) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/modules/video_coding/main/source/video_receiver.cc:318:25 (video_engine_tests+0x000000b8a7d7)
    #8 webrtc::(anonymous namespace)::VideoCodingModuleImpl::Decode(unsigned short) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/modules/video_coding/main/source/video_coding_impl.cc:243:12 (video_engine_tests+0x000000b825b7)
    #9 webrtc::ViEChannel::ChannelDecodeProcess() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/video_engine/vie_channel.cc:1088:3 (video_engine_tests+0x000000884a75)
    #10 webrtc::ViEChannel::ChannelDecodeThreadFunction(void*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/video_engine/vie_channel.cc:1084:10 (video_engine_tests+0x0000008849f8)
    #11 webrtc::ThreadPosix::Run() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/system_wrappers/source/thread_posix.cc:161:10 (video_engine_tests+0x0000008f6d0d)
    #12 webrtc::ThreadPosix::StartThread(void*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/system_wrappers/source/thread_posix.cc:66:3 (video_engine_tests+0x0000008f6998)

  Previous write of size 4 at 0x0000016cae30 by thread T16 (mutexes: write M539):
    #0 InitCpuFlags /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/third_party/libyuv/source/cpu_id.cc:210:13 (video_engine_tests+0x000000988c6f)
    #1 libyuv::TestCpuFlag(int) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/third_party/libyuv/include/libyuv/cpu_id.h:60:35 (video_engine_tests+0x000000989220)
    #2 CopyPlane /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/third_party/libyuv/source/planar_functions.cc:45:7 (video_engine_tests+0x0000009890d2)
    #3 I420Copy /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/third_party/libyuv/source/convert.cc:90:5 (video_engine_tests+0x0000009d1c8e)
    #4 webrtc::VP8DecoderImpl::ReturnFrame(vpx_image const*, unsigned int, long) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc:1341:3 (video_engine_tests+0x000000bd61be)
    #5 webrtc::VP8DecoderImpl::Decode(webrtc::EncodedImage const&, bool, webrtc::RTPFragmentationHeader const*, webrtc::CodecSpecificInfo const*, long) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc:1249:9 (video_engine_tests+0x000000bd5931)
    #6 webrtc::VCMGenericDecoder::Decode(webrtc::VCMEncodedFrame const&, long) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/modules/video_coding/main/source/generic_decoder.cc:154:19 (video_engine_tests+0x000000b6f958)
    #7 webrtc::vcm::VideoReceiver::Decode(webrtc::VCMEncodedFrame const&) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/modules/video_coding/main/source/video_receiver.cc:380:17 (video_engine_tests+0x000000b8abce)
    #8 webrtc::vcm::VideoReceiver::Decode(unsigned short) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/modules/video_coding/main/source/video_receiver.cc:318:25 (video_engine_tests+0x000000b8a7d7)
    #9 webrtc::(anonymous namespace)::VideoCodingModuleImpl::Decode(unsigned short) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/modules/video_coding/main/source/video_coding_impl.cc:243:12 (video_engine_tests+0x000000b825b7)
    #10 webrtc::ViEChannel::ChannelDecodeProcess() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/video_engine/vie_channel.cc:1088:3 (video_engine_tests+0x000000884a75)
    #11 webrtc::ViEChannel::ChannelDecodeThreadFunction(void*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/video_engine/vie_channel.cc:1084:10 (video_engine_tests+0x0000008849f8)
    #12 webrtc::ThreadPosix::Run() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/system_wrappers/source/thread_posix.cc:161:10 (video_engine_tests+0x0000008f6d0d)
    #13 webrtc::ThreadPosix::StartThread(void*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/system_wrappers/source/thread_posix.cc:66:3 (video_engine_tests+0x0000008f6998)

  Location is global 'cpu_info_' of size 4 at 0x0000016cae30 (video_engine_tests+0x0000016cae30)

  Mutex M394 (0x7d0c0000b978) created at:
    #0 pthread_mutex_init <null> (video_engine_tests+0x0000004538d0)
    #1 webrtc::CriticalSectionPosix::CriticalSectionPosix() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/system_wrappers/source/critical_section_posix.cc:24:10 (video_engine_tests+0x0000008f01df)
    #2 webrtc::CriticalSectionWrapper::CreateCriticalSection() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/system_wrappers/source/critical_section.cc:24:14 (video_engine_tests+0x0000008f0128)
    #3 webrtc::vcm::VideoReceiver::VideoReceiver(webrtc::Clock*, webrtc::EventFactory*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/modules/video_coding/main/source/video_receiver.cc:31:24 (video_engine_tests+0x000000b88d6a)
    #4 webrtc::(anonymous namespace)::VideoCodingModuleImpl::VideoCodingModuleImpl(webrtc::Clock*, webrtc::EventFactory*, bool, webrtc::VideoEncoderRateObserver*, webrtc::VCMQMSettingsCallback*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/modules/video_coding/main/source/video_coding_impl.cc:84:23 (video_engine_tests+0x000000b8162e)
    #5 webrtc::VideoCodingModule::Create(webrtc::Clock*, webrtc::VideoEncoderRateObserver*, webrtc::VCMQMSettingsCallback*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/modules/video_coding/main/source/video_coding_impl.cc:345:14 (video_engine_tests+0x000000b814a8)
    #6 webrtc::ViEChannel::ViEChannel(unsigned int, webrtc::Transport*, webrtc::ProcessThread*, webrtc::RtcpIntraFrameObserver*, webrtc::RtcpBandwidthObserver*, webrtc::TransportFeedbackObserver*, webrtc::RemoteBitrateEstimator*, webrtc::RtcpRttStats*, webrtc::PacedSender*, webrtc::PacketRouter*, unsigned long, bool) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/video_engine/vie_channel.cc:98:12 (video_engine_tests+0x000000872fc0)
    #7 webrtc::internal::VideoReceiveStream::VideoReceiveStream(int, webrtc::ChannelGroup*, webrtc::VideoReceiveStream::Config const&, webrtc::VoiceEngine*, webrtc::ProcessThread*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/video/video_receive_stream.cc:158:26 (video_engine_tests+0x00000084fb9b)
    #8 webrtc::internal::Call::CreateVideoReceiveStream(webrtc::VideoReceiveStream::Config const&) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/call/call.cc:334:44 (video_engine_tests+0x000000826b74)
    #9 webrtc::MultiStreamTest::RunTest() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/video/end_to_end_tests.cc:1225:11 (video_engine_tests+0x0000005628d4)
    #10 webrtc::EndToEndTest_SendsAndReceivesMultipleStreams_Test::TestBody() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/video/end_to_end_tests.cc:1335:3 (video_engine_tests+0x000000538c74)
    #11 void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2402:10 (video_engine_tests+0x0000006a8f12)
    #12 void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2455:12 (video_engine_tests+0x000000685f2c)
    #13 testing::Test::Run() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2474:5 (video_engine_tests+0x00000066599b)
    #14 testing::TestInfo::Run() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2656:5 (video_engine_tests+0x0000006668d1)
    #15 testing::TestCase::Run() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2774:5 (video_engine_tests+0x000000667970)
    #16 testing::internal::UnitTestImpl::RunAllTests() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:4647:11 (video_engine_tests+0x0000006779dc)
    #17 bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2402:10 (video_engine_tests+0x0000006aeab2)
    #18 bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2455:12 (video_engine_tests+0x00000068959c)
    #19 testing::UnitTest::Run() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:4255:10 (video_engine_tests+0x000000677469)
    #20 RUN_ALL_TESTS() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../testing/gtest/include/gtest/gtest.h:2237:10 (video_engine_tests+0x0000007f796d)
    #21 main /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/test/test_main.cc:31:10 (video_engine_tests+0x0000007f7876)

  Mutex M539 (0x7d0c00008b28) created at:
    #0 pthread_mutex_init <null> (video_engine_tests+0x0000004538d0)
    #1 webrtc::CriticalSectionPosix::CriticalSectionPosix() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/system_wrappers/source/critical_section_posix.cc:24:10 (video_engine_tests+0x0000008f01df)
    #2 webrtc::CriticalSectionWrapper::CreateCriticalSection() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/system_wrappers/source/critical_section.cc:24:14 (video_engine_tests+0x0000008f0128)
    #3 webrtc::vcm::VideoReceiver::VideoReceiver(webrtc::Clock*, webrtc::EventFactory*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/modules/video_coding/main/source/video_receiver.cc:31:24 (video_engine_tests+0x000000b88d6a)
    #4 webrtc::(anonymous namespace)::VideoCodingModuleImpl::VideoCodingModuleImpl(webrtc::Clock*, webrtc::EventFactory*, bool, webrtc::VideoEncoderRateObserver*, webrtc::VCMQMSettingsCallback*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/modules/video_coding/main/source/video_coding_impl.cc:84:23 (video_engine_tests+0x000000b8162e)
    #5 webrtc::VideoCodingModule::Create(webrtc::Clock*, webrtc::VideoEncoderRateObserver*, webrtc::VCMQMSettingsCallback*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/modules/video_coding/main/source/video_coding_impl.cc:345:14 (video_engine_tests+0x000000b814a8)
    #6 webrtc::ViEChannel::ViEChannel(unsigned int, webrtc::Transport*, webrtc::ProcessThread*, webrtc::RtcpIntraFrameObserver*, webrtc::RtcpBandwidthObserver*, webrtc::TransportFeedbackObserver*, webrtc::RemoteBitrateEstimator*, webrtc::RtcpRttStats*, webrtc::PacedSender*, webrtc::PacketRouter*, unsigned long, bool) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/video_engine/vie_channel.cc:98:12 (video_engine_tests+0x000000872fc0)
    #7 webrtc::internal::VideoReceiveStream::VideoReceiveStream(int, webrtc::ChannelGroup*, webrtc::VideoReceiveStream::Config const&, webrtc::VoiceEngine*, webrtc::ProcessThread*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/video/video_receive_stream.cc:158:26 (video_engine_tests+0x00000084fb9b)
    #8 webrtc::internal::Call::CreateVideoReceiveStream(webrtc::VideoReceiveStream::Config const&) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/call/call.cc:334:44 (video_engine_tests+0x000000826b74)
    #9 webrtc::MultiStreamTest::RunTest() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/video/end_to_end_tests.cc:1225:11 (video_engine_tests+0x0000005628d4)
    #10 webrtc::EndToEndTest_SendsAndReceivesMultipleStreams_Test::TestBody() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/video/end_to_end_tests.cc:1335:3 (video_engine_tests+0x000000538c74)
    #11 void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2402:10 (video_engine_tests+0x0000006a8f12)
    #12 void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2455:12 (video_engine_tests+0x000000685f2c)
    #13 testing::Test::Run() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2474:5 (video_engine_tests+0x00000066599b)
    #14 testing::TestInfo::Run() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2656:5 (video_engine_tests+0x0000006668d1)
    #15 testing::TestCase::Run() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2774:5 (video_engine_tests+0x000000667970)
    #16 testing::internal::UnitTestImpl::RunAllTests() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:4647:11 (video_engine_tests+0x0000006779dc)
    #17 bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2402:10 (video_engine_tests+0x0000006aeab2)
    #18 bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2455:12 (video_engine_tests+0x00000068959c)
    #19 testing::UnitTest::Run() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:4255:10 (video_engine_tests+0x000000677469)
    #20 RUN_ALL_TESTS() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../testing/gtest/include/gtest/gtest.h:2237:10 (video_engine_tests+0x0000007f796d)
    #21 main /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/test/test_main.cc:31:10 (video_engine_tests+0x0000007f7876)

  Thread T10 'DecodingThread' (tid=11650, running) created by main thread at:
    #0 pthread_create <null> (video_engine_tests+0x000000452271)
    #1 webrtc::ThreadPosix::Start() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/system_wrappers/source/thread_posix.cc:97:3 (video_engine_tests+0x0000008f7657)
    #2 webrtc::ViEChannel::StartDecodeThread() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/video_engine/vie_channel.cc:1184:3 (video_engine_tests+0x0000008836b4)
    #3 webrtc::ViEChannel::StartReceive() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/video_engine/vie_channel.cc:962:5 (video_engine_tests+0x0000008834b3)
    #4 webrtc::internal::VideoReceiveStream::Start() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/video/video_receive_stream.cc:308:3 (video_engine_tests+0x000000852dae)
    #5 webrtc::MultiStreamTest::RunTest() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/video/end_to_end_tests.cc:1226:7 (video_engine_tests+0x000000562921)
    #6 webrtc::EndToEndTest_SendsAndReceivesMultipleStreams_Test::TestBody() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/video/end_to_end_tests.cc:1335:3 (video_engine_tests+0x000000538c74)
    #7 void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2402:10 (video_engine_tests+0x0000006a8f12)
    #8 void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2455:12 (video_engine_tests+0x000000685f2c)
    #9 testing::Test::Run() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2474:5 (video_engine_tests+0x00000066599b)
    #10 testing::TestInfo::Run() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2656:5 (video_engine_tests+0x0000006668d1)
    #11 testing::TestCase::Run() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2774:5 (video_engine_tests+0x000000667970)
    #12 testing::internal::UnitTestImpl::RunAllTests() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:4647:11 (video_engine_tests+0x0000006779dc)
    #13 bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2402:10 (video_engine_tests+0x0000006aeab2)
    #14 bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2455:12 (video_engine_tests+0x00000068959c)
    #15 testing::UnitTest::Run() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:4255:10 (video_engine_tests+0x000000677469)
    #16 RUN_ALL_TESTS() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../testing/gtest/include/gtest/gtest.h:2237:10 (video_engine_tests+0x0000007f796d)
    #17 main /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/test/test_main.cc:31:10 (video_engine_tests+0x0000007f7876)

  Thread T16 'DecodingThread' (tid=11683, running) created by main thread at:
    #0 pthread_create <null> (video_engine_tests+0x000000452271)
    #1 webrtc::ThreadPosix::Start() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/system_wrappers/source/thread_posix.cc:97:3 (video_engine_tests+0x0000008f7657)
    #2 webrtc::ViEChannel::StartDecodeThread() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/video_engine/vie_channel.cc:1184:3 (video_engine_tests+0x0000008836b4)
    #3 webrtc::ViEChannel::StartReceive() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/video_engine/vie_channel.cc:962:5 (video_engine_tests+0x0000008834b3)
    #4 webrtc::internal::VideoReceiveStream::Start() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/video/video_receive_stream.cc:308:3 (video_engine_tests+0x000000852dae)
    #5 webrtc::MultiStreamTest::RunTest() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/video/end_to_end_tests.cc:1226:7 (video_engine_tests+0x000000562921)
    #6 webrtc::EndToEndTest_SendsAndReceivesMultipleStreams_Test::TestBody() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/video/end_to_end_tests.cc:1335:3 (video_engine_tests+0x000000538c74)
    #7 void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2402:10 (video_engine_tests+0x0000006a8f12)
    #8 void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2455:12 (video_engine_tests+0x000000685f2c)
    #9 testing::Test::Run() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2474:5 (video_engine_tests+0x00000066599b)
    #10 testing::TestInfo::Run() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2656:5 (video_engine_tests+0x0000006668d1)
    #11 testing::TestCase::Run() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2774:5 (video_engine_tests+0x000000667970)
    #12 testing::internal::UnitTestImpl::RunAllTests() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:4647:11 (video_engine_tests+0x0000006779dc)
    #13 bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2402:10 (video_engine_tests+0x0000006aeab2)
    #14 bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:2455:12 (video_engine_tests+0x00000068959c)
    #15 testing::UnitTest::Run() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/testing/gtest/src/gtest.cc:4255:10 (video_engine_tests+0x000000677469)
    #16 RUN_ALL_TESTS() /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../testing/gtest/include/gtest/gtest.h:2237:10 (video_engine_tests+0x0000007f796d)
    #17 main /usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../webrtc/test/test_main.cc:31:10 (video_engine_tests+0x0000007f7876)

SUMMARY: ThreadSanitizer: data race 
/usr/local/google/home/pbos/webrtc/src/out-tsan/out/Debug/../../../chromium/src/
third_party/libyuv/include/libyuv/cpu_id.h:60:11 in libyuv::TestCpuFlag(int)
==================
[       OK ] EndToEndTest.SendsAndReceivesMultipleStreams (2285 ms)
[----------] 1 test from EndToEndTest (2286 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (2286 ms total)
[  PASSED  ] 1 test.
ThreadSanitizer: reported 1 warnings
ThreadSanitizer: Matched 10 suppressions (pid=11200):
10 race:*trace_event_unique_catstatic*

Original issue reported on code.google.com by pbos@google.com on 19 Oct 2015 at 8:58

GoogleCodeExporter commented 8 years ago
Not sure if bugdroid hangs around here, I committed this in webrtc to suppress 
the race for now, but it'd be nice to be rid of it.

https://codereview.webrtc.org/1414093003/

Original comment by pbos@google.com on 20 Oct 2015 at 12:00

GoogleCodeExporter commented 8 years ago
The global variable is basically a shadow of cpuid flags from the cpu, which 
wont vary.  But the implementation enables/disables the flags as it goes, so it 
is unsafe.
I have a CL that fixes that, so only the final result is written to the global.

The other concern would only be for unittests, but theres a function to disable 
flags.  Its definitely thread unsafe in nature.
e.g.
disable cpu flags
run function1
enable cpu flags
run function2
compare result

during function1, another thread could change the flags.
If the code is working correctly, the only behavior change will be performance.

Its not necessary to use this global... I could query the cpuid directly every 
time.  It just came up high on profiles, whereas the current implementation 
checks the flag in the calling code inline.    Modern cpu detection is getting 
fairly complicated, checking for OS support, so if cpuid were not shadowed, it 
would get increasingly slow in future. 

The cpu dispatching is done on every function call.
Most libraries set up function pointers once.  That would be faster from a 
dispatching point of view, but less flexible and complicates the low level 
assembly.  The SIMD code is simple and only able to do specific widths.. e.g. 
multiple of 16.  The init for those function pointers would probably have the 
same issue.

If the race is coming up in practice, you could call the libyuv::InitCpuFlags() 
once in your startup.

Original comment by fbarch...@google.com on 20 Oct 2015 at 6:13

GoogleCodeExporter commented 8 years ago
For unittests this should be fine, since (I'd expect) you wouldn't change those 
while any test is running.

For this to be totally race free we have to use something like __atomic_load_n 
and __atomic_store_n for the lazy initialization I think. Or mandate that we 
call InitCpuFlags() in webrtc before we use it, but I don't think that we have 
a single common initialization point where we'd put this (for Chromium).

Original comment by pbos@google.com on 21 Oct 2015 at 10:01

GoogleCodeExporter commented 8 years ago
The code now avoids read/modify/write during InitCpuFlags.

You may be able to remove the suppression:

webrtc/build/sanitizers/tsan_suppressions_webrtc.cc
// Race between InitCpuFlags and TestCpuFlag in libyuv.
// https://code.google.com/p/libyuv/issues/detail?id=508
"race:libyuv::TestCpuFlag\n"

Original comment by fbarch...@chromium.org on 22 Oct 2015 at 6:05

GoogleCodeExporter commented 8 years ago
It's still racy (as detected by tsan, true in standard C++ and also true in 
non-x86 assembly), so we can't remove the suppression.

https://chromium.googlesource.com/libyuv/libyuv/+/9be6d21ae726f66bc96502c2498866
d41dcce629/source/cpu_id.cc#293 is not an atomic write, nor is the 
corresponding read atomic. On x86 these have the same performance (x86 
read/writes are acquireload and releasestore), but the compiler isn't allowed 
to do funky optimizations with proper atomics present. Compilers are also 
getting better at doing these funky optimizations.

Something else that you could do if you don't want to use explicit atomics 
(likely slower on any non-x86 platform) is to have cpu_info_ in TLS. Does this 
make sense?

Original comment by pbos@google.com on 22 Oct 2015 at 8:05