forked from OSchip/llvm-project
tsan: add a stress test
The stress test does various assorted things (memory accesses, function calls, atomic operations, thread creation/join, intercepted libc calls) in multiple threads just to stress various parts of the runtime. Reviewed By: melver Differential Revision: https://reviews.llvm.org/D110416
This commit is contained in:
parent
4604695d7c
commit
124fcd7e9d
|
@ -0,0 +1,74 @@
|
|||
// RUN: %clangxx_tsan -O1 %s -o %t && %env_tsan_opts="flush_memory_ms=1 flush_symbolizer_ms=1 memory_limit_mb=1" %run %t 2>&1 | FileCheck %s
|
||||
#include "test.h"
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
volatile long stop;
|
||||
long atomic, read_only;
|
||||
int fds[2];
|
||||
|
||||
__attribute__((noinline)) void *SecondaryThread(void *x) {
|
||||
__atomic_fetch_add(&atomic, 1, __ATOMIC_ACQ_REL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *Thread(void *x) {
|
||||
const int me = (long)x;
|
||||
volatile long sink = 0;
|
||||
while (!stop) {
|
||||
// If me == 0, we do all of the following,
|
||||
// otherwise only 1 type of action.
|
||||
if (me == 0 || me == 1) {
|
||||
// just read the stop variable
|
||||
}
|
||||
if (me == 0 || me == 2) {
|
||||
__atomic_store_n(&atomic, 1, __ATOMIC_RELEASE);
|
||||
}
|
||||
if (me == 0 || me == 3) {
|
||||
sink += __atomic_fetch_add(&atomic, 1, __ATOMIC_ACQ_REL);
|
||||
}
|
||||
if (me == 0 || me == 4) {
|
||||
SecondaryThread(NULL);
|
||||
}
|
||||
if (me == 0 || me == 5) {
|
||||
write(fds[1], fds, 1);
|
||||
}
|
||||
if (me == 0 || me == 6) {
|
||||
char buf[2];
|
||||
read(fds[0], &buf, sizeof(buf));
|
||||
}
|
||||
if (me == 0 || me == 7) {
|
||||
pthread_t th;
|
||||
pthread_create(&th, NULL, SecondaryThread, NULL);
|
||||
pthread_join(th, NULL);
|
||||
}
|
||||
if (me == 0 || me == 8) {
|
||||
long buf;
|
||||
memcpy(&buf, &read_only, sizeof(buf));
|
||||
sink += buf;
|
||||
}
|
||||
// If you add more actions, update kActions in main.
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main() {
|
||||
ANNOTATE_BENIGN_RACE(stop);
|
||||
if (pipe2(fds, O_NONBLOCK))
|
||||
exit((perror("pipe2"), 1));
|
||||
const int kActions = 9;
|
||||
const int kMultiplier = 4;
|
||||
pthread_t t[kActions * kMultiplier];
|
||||
for (int i = 0; i < kActions * kMultiplier; i++)
|
||||
pthread_create(&t[i], NULL, Thread, (void *)(long)(i % kActions));
|
||||
sleep(5);
|
||||
stop = 1;
|
||||
for (int i = 0; i < kActions * kMultiplier; i++)
|
||||
pthread_join(t[i], NULL);
|
||||
fprintf(stderr, "DONE\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// CHECK-NOT: ThreadSanitizer:
|
||||
// CHECK: DONE
|
||||
// CHECK-NOT: ThreadSanitizer:
|
|
@ -88,8 +88,10 @@ void AnnotateIgnoreSyncEnd(const char *f, int l);
|
|||
void AnnotateHappensBefore(const char *f, int l, void *addr);
|
||||
void AnnotateHappensAfter(const char *f, int l, void *addr);
|
||||
|
||||
void AnnotateBenignRaceSized(const char *f, int l, void *mem, unsigned int size, const char *desc);
|
||||
void WTFAnnotateBenignRaceSized(const char *f, int l, void *mem, unsigned int size, const char *desc);
|
||||
void AnnotateBenignRaceSized(const char *f, int l, const volatile void *mem,
|
||||
unsigned int size, const char *desc);
|
||||
void WTFAnnotateBenignRaceSized(const char *f, int l, const volatile void *mem,
|
||||
unsigned int size, const char *desc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue