16a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// RUN: %clangxx_tsan -O1 %s -o %t
26a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// RUN: %run %t 2>&1 | FileCheck %s
36a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// RUN: %run %t arg 2>&1 | FileCheck %s
46a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines#include "java.h"
56a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
66a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hinesjptr varaddr1_old;
76a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hinesjptr varaddr2_old;
86a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hinesjptr lockaddr1_old;
96a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hinesjptr lockaddr2_old;
106a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hinesjptr varaddr1_new;
116a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hinesjptr varaddr2_new;
126a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hinesjptr lockaddr1_new;
136a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hinesjptr lockaddr2_new;
146a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
156a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hinesvoid *Thread(void *p) {
1686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  barrier_wait(&barrier);
176a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  __tsan_java_mutex_lock(lockaddr1_new);
186a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  *(char*)varaddr1_new = 43;
196a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  __tsan_java_mutex_unlock(lockaddr1_new);
206a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  __tsan_java_mutex_lock(lockaddr2_new);
216a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  *(char*)varaddr2_new = 43;
226a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  __tsan_java_mutex_unlock(lockaddr2_new);
236a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  return 0;
246a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines}
256a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
266a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hinesint main(int argc, char **argv) {
2786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  barrier_init(&barrier, 2);
286a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  int const kHeapSize = 1024 * 1024;
296a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  void *jheap = malloc(kHeapSize);
306a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  jheap = (char*)jheap + 8;
316a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  __tsan_java_init((jptr)jheap, kHeapSize);
326a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  const int kBlockSize = 64;
336a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  int const kMove = 32;
346a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  varaddr1_old = (jptr)jheap;
356a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  lockaddr1_old = (jptr)jheap + 1;
366a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  varaddr2_old = (jptr)jheap + kBlockSize - 1;
376a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  lockaddr2_old = (jptr)jheap + kBlockSize - 16;
386a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  varaddr1_new = varaddr1_old + kMove;
396a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  lockaddr1_new = lockaddr1_old + kMove;
406a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  varaddr2_new = varaddr2_old + kMove;
416a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  lockaddr2_new = lockaddr2_old + kMove;
426a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  if (argc > 1) {
436a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    // Move memory backwards.
446a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    varaddr1_old += kMove;
456a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    lockaddr1_old += kMove;
466a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    varaddr2_old += kMove;
476a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    lockaddr2_old += kMove;
486a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    varaddr1_new -= kMove;
496a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    lockaddr1_new -= kMove;
506a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    varaddr2_new -= kMove;
516a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    lockaddr2_new -= kMove;
526a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  }
536a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  __tsan_java_alloc(varaddr1_old, kBlockSize);
546a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
556a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  pthread_t th;
566a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  pthread_create(&th, 0, Thread, 0);
576a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
586a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  __tsan_java_mutex_lock(lockaddr1_old);
596a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  *(char*)varaddr1_old = 43;
606a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  __tsan_java_mutex_unlock(lockaddr1_old);
616a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  __tsan_java_mutex_lock(lockaddr2_old);
626a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  *(char*)varaddr2_old = 43;
636a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  __tsan_java_mutex_unlock(lockaddr2_old);
646a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
656a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  __tsan_java_move(varaddr1_old, varaddr1_new, kBlockSize);
6686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  barrier_wait(&barrier);
676a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  pthread_join(th, 0);
686a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  __tsan_java_free(varaddr1_new, kBlockSize);
69c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  fprintf(stderr, "DONE\n");
706a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines  return __tsan_java_fini();
716a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines}
726a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines
736a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// CHECK-NOT: WARNING: ThreadSanitizer: data race
746a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// CHECK: DONE
75