1*7c3d14c8STreehugger Robot // RUN: %clangxx_tsan -O0 %s -o %t
2*7c3d14c8STreehugger Robot // RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NORMAL
3*7c3d14c8STreehugger Robot // RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-IGNORE
4*7c3d14c8STreehugger Robot
5*7c3d14c8STreehugger Robot #include <errno.h>
6*7c3d14c8STreehugger Robot #include <sys/mman.h>
7*7c3d14c8STreehugger Robot
8*7c3d14c8STreehugger Robot #include "test.h"
9*7c3d14c8STreehugger Robot
10*7c3d14c8STreehugger Robot extern "C" {
11*7c3d14c8STreehugger Robot void AnnotateIgnoreReadsBegin(const char *f, int l);
12*7c3d14c8STreehugger Robot void AnnotateIgnoreReadsEnd(const char *f, int l);
13*7c3d14c8STreehugger Robot void AnnotateIgnoreWritesBegin(const char *f, int l);
14*7c3d14c8STreehugger Robot void AnnotateIgnoreWritesEnd(const char *f, int l);
15*7c3d14c8STreehugger Robot }
16*7c3d14c8STreehugger Robot
17*7c3d14c8STreehugger Robot void *global_p;
18*7c3d14c8STreehugger Robot
mmap_and_ignore_reads_and_writes()19*7c3d14c8STreehugger Robot int mmap_and_ignore_reads_and_writes() {
20*7c3d14c8STreehugger Robot const size_t kSize = sysconf(_SC_PAGESIZE);
21*7c3d14c8STreehugger Robot void *p = mmap(0, kSize, PROT_READ|PROT_WRITE,
22*7c3d14c8STreehugger Robot MAP_PRIVATE|MAP_ANON, -1, 0);
23*7c3d14c8STreehugger Robot if (p == MAP_FAILED)
24*7c3d14c8STreehugger Robot return printf("mmap failed with %d\n", errno);
25*7c3d14c8STreehugger Robot munmap(p, kSize);
26*7c3d14c8STreehugger Robot
27*7c3d14c8STreehugger Robot void *new_p = mmap(p, kSize, PROT_READ|PROT_WRITE,
28*7c3d14c8STreehugger Robot MAP_PRIVATE|MAP_ANON, -1, 0);
29*7c3d14c8STreehugger Robot if (p == MAP_FAILED || p != new_p)
30*7c3d14c8STreehugger Robot return printf("second mmap failed with %d\n", errno);
31*7c3d14c8STreehugger Robot
32*7c3d14c8STreehugger Robot AnnotateIgnoreWritesBegin(__FILE__, __LINE__);
33*7c3d14c8STreehugger Robot global_p = p;
34*7c3d14c8STreehugger Robot AnnotateIgnoreWritesEnd(__FILE__, __LINE__);
35*7c3d14c8STreehugger Robot barrier_wait(&barrier);
36*7c3d14c8STreehugger Robot return 0;
37*7c3d14c8STreehugger Robot }
38*7c3d14c8STreehugger Robot
Thread(void * a)39*7c3d14c8STreehugger Robot void *Thread(void *a) {
40*7c3d14c8STreehugger Robot barrier_wait(&barrier);
41*7c3d14c8STreehugger Robot
42*7c3d14c8STreehugger Robot ((int*)global_p)[1] = 10;
43*7c3d14c8STreehugger Robot printf("Read the zero value from mmapped memory %d\n", ((int*)global_p)[1]);
44*7c3d14c8STreehugger Robot return 0;
45*7c3d14c8STreehugger Robot }
46*7c3d14c8STreehugger Robot
main()47*7c3d14c8STreehugger Robot int main() {
48*7c3d14c8STreehugger Robot barrier_init(&barrier, 2);
49*7c3d14c8STreehugger Robot pthread_t t;
50*7c3d14c8STreehugger Robot pthread_create(&t, 0, Thread, 0);
51*7c3d14c8STreehugger Robot if (mmap_and_ignore_reads_and_writes())
52*7c3d14c8STreehugger Robot return 1;
53*7c3d14c8STreehugger Robot pthread_join(t, 0);
54*7c3d14c8STreehugger Robot printf("OK\n");
55*7c3d14c8STreehugger Robot return 0;
56*7c3d14c8STreehugger Robot }
57*7c3d14c8STreehugger Robot
58*7c3d14c8STreehugger Robot // CHECK-NORMAL: WARNING: ThreadSanitizer: data race
59*7c3d14c8STreehugger Robot // CHECK-NORMAL: OK
60*7c3d14c8STreehugger Robot // CHECK-IGNORE_NOT: WARNING: ThreadSanitizer: data race
61*7c3d14c8STreehugger Robot // CHECK-IGNORE: OK
62