xref: /aosp_15_r20/external/compiler-rt/test/tsan/unaligned_norace.cc (revision 7c3d14c8b49c529e04be81a3ce6f5cc23712e4c6)
1*7c3d14c8STreehugger Robot // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
2*7c3d14c8STreehugger Robot #include <pthread.h>
3*7c3d14c8STreehugger Robot #include <stdio.h>
4*7c3d14c8STreehugger Robot #include <stdlib.h>
5*7c3d14c8STreehugger Robot #include <stdint.h>
6*7c3d14c8STreehugger Robot 
7*7c3d14c8STreehugger Robot uint64_t objs[8*3*3*2][3];
8*7c3d14c8STreehugger Robot 
9*7c3d14c8STreehugger Robot extern "C" {
10*7c3d14c8STreehugger Robot void __tsan_unaligned_read2(void *addr);
11*7c3d14c8STreehugger Robot void __tsan_unaligned_read4(void *addr);
12*7c3d14c8STreehugger Robot void __tsan_unaligned_read8(void *addr);
13*7c3d14c8STreehugger Robot void __tsan_unaligned_write2(void *addr);
14*7c3d14c8STreehugger Robot void __tsan_unaligned_write4(void *addr);
15*7c3d14c8STreehugger Robot void __tsan_unaligned_write8(void *addr);
16*7c3d14c8STreehugger Robot }
17*7c3d14c8STreehugger Robot 
access(char * p,int sz,int rw)18*7c3d14c8STreehugger Robot static void access(char *p, int sz, int rw) {
19*7c3d14c8STreehugger Robot   if (rw) {
20*7c3d14c8STreehugger Robot     switch (sz) {
21*7c3d14c8STreehugger Robot     case 0: __tsan_unaligned_write2(p); break;
22*7c3d14c8STreehugger Robot     case 1: __tsan_unaligned_write4(p); break;
23*7c3d14c8STreehugger Robot     case 2: __tsan_unaligned_write8(p); break;
24*7c3d14c8STreehugger Robot     default: exit(1);
25*7c3d14c8STreehugger Robot     }
26*7c3d14c8STreehugger Robot   } else {
27*7c3d14c8STreehugger Robot     switch (sz) {
28*7c3d14c8STreehugger Robot     case 0: __tsan_unaligned_read2(p); break;
29*7c3d14c8STreehugger Robot     case 1: __tsan_unaligned_read4(p); break;
30*7c3d14c8STreehugger Robot     case 2: __tsan_unaligned_read8(p); break;
31*7c3d14c8STreehugger Robot     default: exit(1);
32*7c3d14c8STreehugger Robot     }
33*7c3d14c8STreehugger Robot   }
34*7c3d14c8STreehugger Robot }
35*7c3d14c8STreehugger Robot 
accesssize(int sz)36*7c3d14c8STreehugger Robot static int accesssize(int sz) {
37*7c3d14c8STreehugger Robot   switch (sz) {
38*7c3d14c8STreehugger Robot   case 0: return 2;
39*7c3d14c8STreehugger Robot   case 1: return 4;
40*7c3d14c8STreehugger Robot   case 2: return 8;
41*7c3d14c8STreehugger Robot   }
42*7c3d14c8STreehugger Robot   exit(1);
43*7c3d14c8STreehugger Robot }
44*7c3d14c8STreehugger Robot 
Test(bool main)45*7c3d14c8STreehugger Robot void Test(bool main) {
46*7c3d14c8STreehugger Robot   uint64_t *obj = objs[0];
47*7c3d14c8STreehugger Robot   for (int off = 0; off < 8; off++) {
48*7c3d14c8STreehugger Robot     for (int sz1 = 0; sz1 < 3; sz1++) {
49*7c3d14c8STreehugger Robot       for (int sz2 = 0; sz2 < 3; sz2++) {
50*7c3d14c8STreehugger Robot         for (int rw = 0; rw < 2; rw++) {
51*7c3d14c8STreehugger Robot           char *p = (char*)obj + off;
52*7c3d14c8STreehugger Robot           if (main) {
53*7c3d14c8STreehugger Robot             // printf("thr=%d off=%d sz1=%d sz2=%d rw=%d p=%p\n",
54*7c3d14c8STreehugger Robot             //        main, off, sz1, sz2, rw, p);
55*7c3d14c8STreehugger Robot             access(p, sz1, true);
56*7c3d14c8STreehugger Robot           } else {
57*7c3d14c8STreehugger Robot             p += accesssize(sz1);
58*7c3d14c8STreehugger Robot             // printf("thr=%d off=%d sz1=%d sz2=%d rw=%d p=%p\n",
59*7c3d14c8STreehugger Robot             //        main, off, sz1, sz2, rw, p);
60*7c3d14c8STreehugger Robot             access(p, sz2, rw);
61*7c3d14c8STreehugger Robot           }
62*7c3d14c8STreehugger Robot           obj += 3;
63*7c3d14c8STreehugger Robot         }
64*7c3d14c8STreehugger Robot       }
65*7c3d14c8STreehugger Robot     }
66*7c3d14c8STreehugger Robot   }
67*7c3d14c8STreehugger Robot }
68*7c3d14c8STreehugger Robot 
Thread(void * p)69*7c3d14c8STreehugger Robot void *Thread(void *p) {
70*7c3d14c8STreehugger Robot   (void)p;
71*7c3d14c8STreehugger Robot   Test(false);
72*7c3d14c8STreehugger Robot   return 0;
73*7c3d14c8STreehugger Robot }
74*7c3d14c8STreehugger Robot 
main()75*7c3d14c8STreehugger Robot int main() {
76*7c3d14c8STreehugger Robot   pthread_t th;
77*7c3d14c8STreehugger Robot   pthread_create(&th, 0, Thread, 0);
78*7c3d14c8STreehugger Robot   Test(true);
79*7c3d14c8STreehugger Robot   pthread_join(th, 0);
80*7c3d14c8STreehugger Robot   fprintf(stderr, "OK\n");
81*7c3d14c8STreehugger Robot }
82*7c3d14c8STreehugger Robot 
83*7c3d14c8STreehugger Robot // CHECK-NOT: WARNING: ThreadSanitizer:
84*7c3d14c8STreehugger Robot // CHECK: OK
85