1*db2f870fSDmitry Vyukov // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
2bcaeed49SFangrui Song #include "java.h"
3bcaeed49SFangrui Song
4bcaeed49SFangrui Song jptr varaddr;
5bcaeed49SFangrui Song jptr varaddr2;
6bcaeed49SFangrui Song
Thread(void * p)7bcaeed49SFangrui Song void *Thread(void *p) {
8bcaeed49SFangrui Song barrier_wait(&barrier);
9bcaeed49SFangrui Song *(int*)varaddr2 = 42;
10bcaeed49SFangrui Song return 0;
11bcaeed49SFangrui Song }
12bcaeed49SFangrui Song
main()13bcaeed49SFangrui Song int main() {
14bcaeed49SFangrui Song barrier_init(&barrier, 2);
15bcaeed49SFangrui Song int const kHeapSize = 1024 * 1024;
16bcaeed49SFangrui Song jptr jheap = (jptr)malloc(kHeapSize + 8) + 8;
17bcaeed49SFangrui Song __tsan_java_init(jheap, kHeapSize);
18bcaeed49SFangrui Song const int kBlockSize = 64;
19bcaeed49SFangrui Song int const kMove = 1024;
20bcaeed49SFangrui Song __tsan_java_alloc(jheap, kBlockSize);
21bcaeed49SFangrui Song varaddr = jheap + 16;
22bcaeed49SFangrui Song varaddr2 = varaddr + kMove;
23bcaeed49SFangrui Song pthread_t th;
24bcaeed49SFangrui Song pthread_create(&th, 0, Thread, 0);
25bcaeed49SFangrui Song *(int*)varaddr = 43;
26bcaeed49SFangrui Song __tsan_java_move(varaddr, varaddr2, kBlockSize);
27bcaeed49SFangrui Song barrier_wait(&barrier);
28bcaeed49SFangrui Song pthread_join(th, 0);
29bcaeed49SFangrui Song __tsan_java_free(varaddr2, kBlockSize);
30bcaeed49SFangrui Song fprintf(stderr, "DONE\n");
31bcaeed49SFangrui Song return __tsan_java_fini();
32bcaeed49SFangrui Song }
33bcaeed49SFangrui Song
34*db2f870fSDmitry Vyukov // Note: there is a race on the moved object (which we used to detect),
35*db2f870fSDmitry Vyukov // but now __tsan_java_move resets the object shadow, so we don't detect it anymore.
36*db2f870fSDmitry Vyukov // CHECK-NOT: WARNING: ThreadSanitizer: data race
37bcaeed49SFangrui Song // CHECK: DONE
38