I created the following simple test program to see how parallel execution works with std::for_each.
#include <iostream>
#include <vector>
#include <execution>
int main(int ac, char**av){
constexpr int size=5;
std::vector<int> v;
std::vector<int> expected;
for(int i=0; i<size; ++i) v.push_back(i);
expected.resize(size);
std::for_each(std::execution::par, v.begin(), v.end(), [&](auto x){ expected[x]=x; });
auto eq = std::equal(v.begin(), v.end(), expected.begin());
std::cout << "Compare: "<<eq<<"\n";
return 0;
}
The program runs without any problem, however if I link it with thread sanitized I get data race warnings. Here is the program output:
Compare: 1
==================
WARNING: ThreadSanitizer: data race (pid=47090)
Write of size 8 at 0x7fab5399b200 by thread T8:
#0 memset /tp_src/gcc-9.2.0/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:762 (libtsan.so.10+0x35bc5)
#1 memset /tp_src/gcc-9.2.0/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:760 (libtsan.so.10+0x35bc5)
#2 rml::internal::BootStrapBlocks::allocate(rml::internal::MemoryPool*, unsigned long) ../../src/tbbmalloc/frontend.cpp:888 (libtbbmalloc.so.2+0x13700)
Previous write of size 8 at 0x7fab5399b200 by thread T10:
#0 memset /tp_src/gcc-9.2.0/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:762 (libtsan.so.10+0x35bc5)
#1 memset /tp_src/gcc-9.2.0/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:760 (libtsan.so.10+0x35bc5)
#2 rml::internal::BootStrapBlocks::allocate(rml::internal::MemoryPool*, unsigned long) ../../src/tbbmalloc/frontend.cpp:888 (libtbbmalloc.so.2+0x13700)
Thread T8 (tid=47099, running) created by thread T4 at:
#0 pthread_create /tp_src/gcc-9.2.0/libsanitizer/tsan/tsan_interceptors.cc:964 (libtsan.so.10+0x3057b)
#1 rml::internal::thread_monitor::launch(void* (*)(void*), void*, unsigned long) ../../src/tbb/../rml/server/thread_monitor.h:218 (libtbb.so.2+0x20ab8)
#2 tbb::internal::rml::private_worker::wake_or_launch() ../../src/tbb/private_server.cpp:297 (libtbb.so.2+0x20ab8)
#3 tbb::internal::rml::private_server::wake_some(int) ../../src/tbb/private_server.cpp:395 (libtbb.so.2+0x20ab8)
Thread T10 (tid=47101, running) created by thread T3 at:
#0 pthread_create /tp_src/gcc-9.2.0/libsanitizer/tsan/tsan_interceptors.cc:964 (libtsan.so.10+0x3057b)
#1 rml::internal::thread_monitor::launch(void* (*)(void*), void*, unsigned long) ../../src/tbb/../rml/server/thread_monitor.h:218 (libtbb.so.2+0x20ab8)
#2 tbb::internal::rml::private_worker::wake_or_launch() ../../src/tbb/private_server.cpp:297 (libtbb.so.2+0x20ab8)
#3 tbb::internal::rml::private_server::wake_some(int) ../../src/tbb/private_server.cpp:395 (libtbb.so.2+0x20ab8)
SUMMARY: ThreadSanitizer: data race ../../src/tbbmalloc/frontend.cpp:888 in rml::internal::BootStrapBlocks::allocate(rml::internal::MemoryPool*, unsigned long) [83/16871]
==================
It looks like for_each has completed and comparison in the end have succeeded. However some background threads make thread sanitizer unhappy during completion of main.
Are there any issues with this example or this is a bug or a false positive warning in thread sanitizer and I can ignore it?
Here is how I compile it:
g++ -O3 -I$TBBINC -std=c++17 -fsanitize=thread ForEach.cpp $TBBLIB/libtbb.so -o ForEach