[compiler-rt][builtins] Add opt-in pthread_mutex_t locks to libatomic (#95326)
When an uninstrumented libatomic is used with a TSan instrumented memcpy, TSan may report a data race in circumstances where writes are arguably safe. This occurs because __atomic_compare_exchange won't be instrumented in an uninstrumented libatomic, so TSan doesn't know that the subsequent memcpy is race-free. On the other hand, pthread_mutex_(un)lock will be intercepted by TSan, meaning an uninstrumented libatomic will not report this false-positive. pthread_mutexes also may try a number of different strategies to acquire the lock, which may bound the amount of time a thread has to wait for a lock during contention. While pthread_mutex_lock has a larger overhead (due to the function call and some dispatching), a dispatch to libatomic already predicates a lack of performance guarantees.
This commit is contained in:
parent
a239343521
commit
6499c5d70c
@ -237,6 +237,14 @@ if(NOT FUCHSIA AND NOT COMPILER_RT_BAREMETAL_BUILD)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
option(COMPILER_RT_LIBATOMIC_USE_PTHREAD
|
||||||
|
"Whether libatomic should use pthreads if available."
|
||||||
|
Off)
|
||||||
|
|
||||||
|
if(COMPILER_RT_LIBATOMIC_USE_PTHREAD)
|
||||||
|
add_compile_definitions(_LIBATOMIC_USE_PTHREAD)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(COMPILER_RT_HAS_ATOMIC_KEYWORD AND NOT COMPILER_RT_EXCLUDE_ATOMIC_BUILTIN)
|
if(COMPILER_RT_HAS_ATOMIC_KEYWORD AND NOT COMPILER_RT_EXCLUDE_ATOMIC_BUILTIN)
|
||||||
set(GENERIC_SOURCES
|
set(GENERIC_SOURCES
|
||||||
${GENERIC_SOURCES}
|
${GENERIC_SOURCES}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
//
|
//
|
||||||
// 1) This code must work with C programs that do not link to anything
|
// 1) This code must work with C programs that do not link to anything
|
||||||
// (including pthreads) and so it should not depend on any pthread
|
// (including pthreads) and so it should not depend on any pthread
|
||||||
// functions.
|
// functions. If the user wishes to opt into using pthreads, they may do so.
|
||||||
// 2) Atomic operations, rather than explicit mutexes, are most commonly used
|
// 2) Atomic operations, rather than explicit mutexes, are most commonly used
|
||||||
// on code where contended operations are rate.
|
// on code where contended operations are rate.
|
||||||
//
|
//
|
||||||
@ -56,7 +56,17 @@ static const long SPINLOCK_MASK = SPINLOCK_COUNT - 1;
|
|||||||
// defined. Each platform should define the Lock type, and corresponding
|
// defined. Each platform should define the Lock type, and corresponding
|
||||||
// lock() and unlock() functions.
|
// lock() and unlock() functions.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
#if defined(_LIBATOMIC_USE_PTHREAD)
|
||||||
|
#include <pthread.h>
|
||||||
|
typedef pthread_mutex_t Lock;
|
||||||
|
/// Unlock a lock. This is a release operation.
|
||||||
|
__inline static void unlock(Lock *l) { pthread_mutex_unlock(l); }
|
||||||
|
/// Locks a lock.
|
||||||
|
__inline static void lock(Lock *l) { pthread_mutex_lock(l); }
|
||||||
|
/// locks for atomic operations
|
||||||
|
static Lock locks[SPINLOCK_COUNT];
|
||||||
|
|
||||||
|
#elif defined(__FreeBSD__) || defined(__DragonFly__)
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user