Add a contended SPSC stress suite (tests/test_channel_stress.cpp) that actually exercises the ring's memory-ordering pairing and spin/futex/ lost-wakeup logic, plus the CMake and CI plumbing to run it under TSan: - KPN_SANITIZER cache var + kpn_sanitizer_flags() helper (no-op when unset) - kpn_tests_stress executable, labelled "stress" for CTest - reusable tsan.yaml workflow (gcc:14 builder image, already ships libtsan) - ci.yaml gains a tsan job on the same code/dockerfile triggers as test Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
68 lines
2.3 KiB
YAML
68 lines
2.3 KiB
YAML
name: '🧵 ThreadSanitizer'
|
|
|
|
# Reusable workflow: builds the channel stress suite with ThreadSanitizer and
|
|
# runs it. This is the dynamic half of verifying the lock-free SPSC Channel<T>
|
|
# (the static half is the CDSChecker model-check harness in verify/).
|
|
#
|
|
# Triggering and path filtering are owned by ci.yaml (the orchestrator), which
|
|
# calls this only when code changed. workflow_dispatch is kept for manual runs.
|
|
#
|
|
# Runs in the prebuilt builder image (gcc:14), which already ships libtsan — no
|
|
# package installs at job time.
|
|
on:
|
|
workflow_call:
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
tsan:
|
|
runs-on: linux/amd64
|
|
container:
|
|
image: gitea.tourolle.paris/dtourolle/kpnpp-builder:latest
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
with:
|
|
path: tsan-${{ github.run_id }}
|
|
|
|
- name: Cache FetchContent dependencies
|
|
uses: actions/cache@v3
|
|
with:
|
|
path: ~/.cmake/fetchcontent
|
|
key: cmake-fetchcontent-${{ hashFiles('**/CMakeLists.txt') }}
|
|
restore-keys: cmake-fetchcontent-
|
|
|
|
- name: Configure (TSan)
|
|
working-directory: tsan-${{ github.run_id }}
|
|
run: |
|
|
cmake -S . -B build \
|
|
-G Ninja \
|
|
-DCMAKE_BUILD_TYPE=Debug \
|
|
-DKPN_SANITIZER=thread \
|
|
-DKPN_BUILD_TESTS=ON \
|
|
-DKPN_BUILD_EXAMPLES=OFF \
|
|
-DKPN_BUILD_PYTHON=OFF \
|
|
-DFETCHCONTENT_BASE_DIR=$HOME/.cmake/fetchcontent
|
|
|
|
- name: Build (TSan)
|
|
working-directory: tsan-${{ github.run_id }}
|
|
run: cmake --build build --parallel --target kpn_tests kpn_tests_stress
|
|
|
|
- name: Run stress suite under TSan
|
|
working-directory: tsan-${{ github.run_id }}
|
|
# halt_on_error=1 makes the first detected race fail the job; the report
|
|
# (with both stacks) is printed to the log. second_deadlock_stack gives
|
|
# the full picture for lock-order issues.
|
|
env:
|
|
TSAN_OPTIONS: "halt_on_error=1 second_deadlock_stack=1"
|
|
run: ./build/tests/kpn_tests_stress
|
|
|
|
- name: Run unit tests under TSan
|
|
working-directory: tsan-${{ github.run_id }}
|
|
env:
|
|
TSAN_OPTIONS: "halt_on_error=1 second_deadlock_stack=1"
|
|
run: ./build/tests/kpn_tests
|
|
|
|
- name: Cleanup
|
|
if: always()
|
|
run: rm -rf tsan-${{ github.run_id }}
|