10 #include <sys/types.h>
13 #define MiB(a) ((a)*1024*1024)
16 void err_exit(char *op)
18 fprintf(stderr, "%s: %s\n", op, strerror(errno));
22 void worker_fn(void *ptr)
24 char *data = (char *)ptr;
28 for (i = 0; i < 10; i++) {
32 err = madvise(data, MiB(2), MADV_DONTNEED);
36 /* Mix up the thread timings to encourage the race. */
37 err = usleep(rand() % 100);
43 int main(int argc, char *argv[])
45 pthread_t thread[NUM_THREADS];
50 printf("Usage: %s <file>\n", basename(argv[0]));
54 fd = open(argv[1], O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
58 /* This allows us to map a huge page. */
60 ftruncate(fd, MiB(2));
63 * First we set up a shared mapping. Our write will (hopefully) get
64 * the filesystem to give us a 2MiB huge page DAX mapping. We will
65 * then use this 2MiB page for our private mapping race.
67 data = mmap(NULL, MiB(2), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
68 if (data == MAP_FAILED)
69 err_exit("shared mmap");
73 err = munmap(data, MiB(2));
75 err_exit("shared munmap");
77 for (i = 0; i < 500; i++) {
78 data = mmap(NULL, MiB(2), PROT_READ|PROT_WRITE, MAP_PRIVATE,
80 if (data == MAP_FAILED)
81 err_exit("private mmap");
83 for (j = 0; j < NUM_THREADS; j++) {
84 err = pthread_create(&thread[j], NULL,
85 (void*)&worker_fn, data);
87 err_exit("pthread_create");
90 for (j = 0; j < NUM_THREADS; j++) {
91 err = pthread_join(thread[j], NULL);
93 err_exit("pthread_join");
96 err = munmap(data, MiB(2));
98 err_exit("private munmap");