diff --git a/.github/workflows/ubuntu18-threadsani.yml b/.github/workflows/ubuntu18-threadsani.yml new file mode 100644 index 000000000..b30a59a09 --- /dev/null +++ b/.github/workflows/ubuntu18-threadsani.yml @@ -0,0 +1,27 @@ +name: Ubuntu 18.04 CI (GCC 7) with Thread Sanitizer + +on: + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + ubuntu-build: + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + with: + path: dependencies/.cache + key: ${{ hashFiles('dependencies/CMakeLists.txt') }} + - name: Use cmake + run: | + mkdir build && + cd build && + cmake -DSIMDJSON_SANITIZE_THREADS=ON .. && + cmake --build . --target document_stream_tests --target parse_many_test && + ctest --output-on-failure -R parse_many_test && + ctest --output-on-failure -R document_stream_tests \ No newline at end of file diff --git a/.github/workflows/ubuntu20-threadsani.yml b/.github/workflows/ubuntu20-threadsani.yml new file mode 100644 index 000000000..cd6a44df6 --- /dev/null +++ b/.github/workflows/ubuntu20-threadsani.yml @@ -0,0 +1,27 @@ +name: Ubuntu 20.04 CI (GCC 9) with Thread Sanitizer + +on: + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + ubuntu-build: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - uses: actions/cache@v2 + with: + path: dependencies/.cache + key: ${{ hashFiles('dependencies/CMakeLists.txt') }} + - name: Use cmake + run: | + mkdir build && + cd build && + cmake -DSIMDJSON_SANITIZE_THREADS=ON .. && + cmake --build . --target document_stream_tests --target parse_many_test && + ctest --output-on-failure -R parse_many_test && + ctest --output-on-failure -R document_stream_tests \ No newline at end of file diff --git a/cmake/simdjson-flags.cmake b/cmake/simdjson-flags.cmake index 4330ee68d..7ffb4a48e 100644 --- a/cmake/simdjson-flags.cmake +++ b/cmake/simdjson-flags.cmake @@ -27,6 +27,15 @@ if(SIMDJSON_SANITIZE) endif() endif() +if(SIMDJSON_SANITIZE_THREADS) + target_compile_options(simdjson-flags INTERFACE -fsanitize=thread -fsanitize=undefined -fno-sanitize-recover=all) + target_link_libraries(simdjson-flags INTERFACE -fsanitize=thread -fsanitize=undefined -fno-sanitize-recover=all) + + # Ubuntu bug for GCC 5.0+ (safe for all versions) + if (CMAKE_COMPILER_IS_GNUCC) + target_link_libraries(simdjson-flags INTERFACE -fuse-ld=gold) + endif() +endif() if (NOT CMAKE_BUILD_TYPE) message(STATUS "No build type selected, default to Release") diff --git a/include/simdjson/dom/document_stream-inl.h b/include/simdjson/dom/document_stream-inl.h index 251285fe2..1058d0479 100644 --- a/include/simdjson/dom/document_stream-inl.h +++ b/include/simdjson/dom/document_stream-inl.h @@ -24,7 +24,7 @@ inline void stage1_worker::start_thread() { return; // This should never happen but we never want to create more than one thread. } thread = std::thread([this]{ - while(can_work) { + while(true) { std::unique_lock thread_lock(locking_mutex); cond_var.wait(thread_lock, [this]{return has_work || !can_work;}); if(!can_work) {