llvm-project

Форк
0
/
unaligned_race.cpp 
129 строк · 3.2 Кб
1
// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
2
#include "test.h"
3
#include <stdint.h>
4

5
#define NOINLINE __attribute__((noinline))
6

7
volatile 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

12
static 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

30
static 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

39
template<int off, int off2>
40
static 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

55
template<int off>
56
static NOINLINE void
57
access2(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

76
static NOINLINE void
77
access1(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

96
NOINLINE 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

112
void *Thread(void *p) {
113
  (void)p;
114
  barrier_wait(&barrier);
115
  Test(false);
116
  return 0;
117
}
118

119
int 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 race
129
// CHECK: ThreadSanitizer: reported 224 warnings
130

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.