brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.2 KiB · 5850b21 Raw
130 lines · cpp
1// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s2#include "test.h"3#include <stdint.h>4 5#define NOINLINE __attribute__((noinline))6 7volatile uint64_t objs[8*2*(2 + 4 + 8)][2];8 9// All this mess is to generate unique stack for each race,10// otherwise tsan will suppress similar stacks.11 12static NOINLINE void access(volatile void *p, int sz, int rw) {13  if (rw) {14    switch (sz) {15    case 0: __sanitizer_unaligned_store16((void *)p, 0); break;16    case 1: __sanitizer_unaligned_store32((void *)p, 0); break;17    case 2: __sanitizer_unaligned_store64((void *)p, 0); break;18    default: exit(1);19    }20  } else {21    switch (sz) {22    case 0: __sanitizer_unaligned_load16((void *)p); break;23    case 1: __sanitizer_unaligned_load32((void *)p); break;24    case 2: __sanitizer_unaligned_load64((void *)p); break;25    default: exit(1);26    }27  }28}29 30static int accesssize(int sz) {31  switch (sz) {32  case 0: return 2;33  case 1: return 4;34  case 2: return 8;35  }36  exit(1);37}38 39template<int off, int off2>40static NOINLINE void access3(bool main, int sz1, bool rw, volatile char *p) {41  p += off;42  if (main) {43    access(p, sz1, true);44  } else {45    p += off2;46    if (rw) {47      *p = 42;48    } else {49       if (*p == 42)50         printf("bingo!\n");51    }52  }53}54 55template<int off>56static NOINLINE void57access2(bool main, int sz1, int off2, bool rw, volatile char *obj) {58  if (off2 == 0)59    access3<off, 0>(main, sz1, rw, obj);60  else if (off2 == 1)61    access3<off, 1>(main, sz1, rw, obj);62  else if (off2 == 2)63    access3<off, 2>(main, sz1, rw, obj);64  else if (off2 == 3)65    access3<off, 3>(main, sz1, rw, obj);66  else if (off2 == 4)67    access3<off, 4>(main, sz1, rw, obj);68  else if (off2 == 5)69    access3<off, 5>(main, sz1, rw, obj);70  else if (off2 == 6)71    access3<off, 6>(main, sz1, rw, obj);72  else if (off2 == 7)73    access3<off, 7>(main, sz1, rw, obj);74}75 76static NOINLINE void77access1(bool main, int off, int sz1, int off2, bool rw, char *obj) {78  if (off == 0)79    access2<0>(main, sz1, off2, rw, obj);80  else if (off == 1)81    access2<1>(main, sz1, off2, rw, obj);82  else if (off == 2)83    access2<2>(main, sz1, off2, rw, obj);84  else if (off == 3)85    access2<3>(main, sz1, off2, rw, obj);86  else if (off == 4)87    access2<4>(main, sz1, off2, rw, obj);88  else if (off == 5)89    access2<5>(main, sz1, off2, rw, obj);90  else if (off == 6)91    access2<6>(main, sz1, off2, rw, obj);92  else if (off == 7)93    access2<7>(main, sz1, off2, rw, obj);94}95 96NOINLINE void Test(bool main) {97  volatile uint64_t *obj = objs[0];98  for (int off = 0; off < 8; off++) {99    for (int sz1 = 0; sz1 < 3; sz1++) {100      for (int off2 = 0; off2 < accesssize(sz1); off2++) {101        for (int rw = 0; rw < 2; rw++) {102          // printf("thr=%d off=%d sz1=%d off2=%d rw=%d p=%p\n",103          //        main, off, sz1, off2, rw, obj);104          access1(main, off, sz1, off2, rw, (char*)obj);105          obj += 2;106        }107      }108    }109  }110}111 112void *Thread(void *p) {113  (void)p;114  barrier_wait(&barrier);115  Test(false);116  return 0;117}118 119int main() {120  barrier_init(&barrier, 2);121  pthread_t th;122  pthread_create(&th, 0, Thread, 0);123  Test(true);124  barrier_wait(&barrier);125  pthread_join(th, 0);126}127 128// CHECK: WARNING: ThreadSanitizer: data race129// CHECK: ThreadSanitizer: reported 224 warnings130