Add configuration option to make assertions thread-safe
All the previous refactoring to make the assertion fast paths smaller and faster also allows us to implement the fast paths just with thread-local and atomic variables, without full mutexes. However, the performance overhead of thread-safe assertions is still significant for single threaded usage: | slowdown | Debug | Release | |-----------|--------:|--------:| | fast path | 1.04x | 1.43x | | slow path | 1.16x | 1.22x | Thus, we don't make the assertions thread-safe by default, and instead provide a build-time configuration option that the users can set to get thread-safe assertions. This commit is functional, but it still needs some follow-up work: * We do not need full seq_cst increments for the atomic counters, and using weaker ones can be faster. * We brute-force updating the reporter-friendly totals from internal atomic counters by doing it everywhere. We should properly trace where this is needed instead. * Message macros (`INFO`, `UNSCOPED_INFO`, `CAPTURE`, etc) are not made thread safe in this commit, but they can be made thread safe in the future, by building on top of this work. * Add more tests, including with thread-sanitizer, and compiled examples to the repository. Right now, these changes have been compiled with tsan manually, but these tests are not added to CI. Closes #2948
This commit is contained in:
12 files changed
+332
-49
No files matched your search
@@ -0,0 +1,49 @@
|
||||
|
||||
// Copyright Catch2 Authors
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE.txt or copy at
|
||||
// https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
#ifndef CATCH_THREAD_SUPPORT_HPP_INCLUDED
|
||||
#define CATCH_THREAD_SUPPORT_HPP_INCLUDED
|
||||
|
||||
#include <catch2/catch_user_config.hpp>
|
||||
|
||||
#if defined( CATCH_CONFIG_EXPERIMENTAL_THREAD_SAFE_ASSERTIONS )
|
||||
# include <atomic>
|
||||
# include <mutex>
|
||||
#endif
|
||||
|
||||
#include <catch2/catch_totals.hpp>
|
||||
|
||||
namespace Catch {
|
||||
namespace Detail {
|
||||
#if defined( CATCH_CONFIG_EXPERIMENTAL_THREAD_SAFE_ASSERTIONS )
|
||||
using Mutex = std::mutex;
|
||||
using LockGuard = std::lock_guard<std::mutex>;
|
||||
struct AtomicCounts {
|
||||
std::atomic<std::uint64_t> passed = 0;
|
||||
std::atomic<std::uint64_t> failed = 0;
|
||||
std::atomic<std::uint64_t> failedButOk = 0;
|
||||
std::atomic<std::uint64_t> skipped = 0;
|
||||
};
|
||||
#else // ^^ Use actual mutex, lock and atomics
|
||||
// vv Dummy implementations for single-thread performance
|
||||
|
||||
struct Mutex {
|
||||
void lock() {}
|
||||
void unlock() {}
|
||||
};
|
||||
|
||||
struct LockGuard {
|
||||
LockGuard( Mutex ) {}
|
||||
};
|
||||
|
||||
using AtomicCounts = Counts;
|
||||
#endif
|
||||
|
||||
} // namespace Detail
|
||||
} // namespace Catch
|
||||
|
||||
#endif // CATCH_THREAD_SUPPORT_HPP_INCLUDED
|
||||
Reference in new issue
Block a user