mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-17 07:16:41 +00:00

Currently __tsan_atomic* functions do FuncEntry/Exit using caller PC and then use current PC (pointing to __tsan_atomic* itself) during memory access handling. As the result the top function in reports involving atomics is __tsan_atomic* and the next frame points to user code. Remove FuncEntry/Exit in atomic functions and use caller PC during memory access handling. This removes __tsan_atomic* from the top of report stacks, so that they point right to user code. The motivation for this is performance. Some atomic operations are very hot (mostly loads), so removing FuncEntry/Exit is beneficial. This also reduces thread trace consumption (1 event instead of 3). __tsan_atomic* at the top of the stack is not necessary and does not add any new information. We already say "atomic write of size 4", "__tsan_atomic32_store" does not add anything new. It also makes reports consistent between atomic and non-atomic accesses. For normal accesses we say "previous write" and point to user code; for atomics we say "previous atomic write" and now also point to user code. Reviewed By: vitalybuka Differential Revision: https://reviews.llvm.org/D106966
30 lines
621 B
C++
30 lines
621 B
C++
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
|
|
#include "test.h"
|
|
|
|
int Global;
|
|
|
|
void *Thread1(void *x) {
|
|
barrier_wait(&barrier);
|
|
__atomic_fetch_add(&Global, 1, __ATOMIC_RELAXED);
|
|
return NULL;
|
|
}
|
|
|
|
void *Thread2(void *x) {
|
|
Global++;
|
|
barrier_wait(&barrier);
|
|
return NULL;
|
|
}
|
|
|
|
int main() {
|
|
barrier_init(&barrier, 2);
|
|
pthread_t t[2];
|
|
pthread_create(&t[0], NULL, Thread1, NULL);
|
|
pthread_create(&t[1], NULL, Thread2, NULL);
|
|
pthread_join(t[0], NULL);
|
|
pthread_join(t[1], NULL);
|
|
}
|
|
|
|
// CHECK: WARNING: ThreadSanitizer: data race
|
|
// CHECK: Atomic write of size 4
|
|
// CHECK: #0 Thread1
|