11 #ifdef HAVE_LIBPTHREAD
16 * Usage: rw_seq_cst_vs_drop_caches [-m] /mnt/lustre/file0 /mnt/lustre2/file0
18 * Race reads of the same file on two client mounts vs writes and drop
19 * caches to detect sequential consistency violations. Run
20 * indefinately. all abort() if a consistency violation is found in
21 * which case the wait status ($?) will be 134.
24 int mmap_mode; /* -m flag */
26 static void usage(void)
29 "%s: rw_seq_cst_vs_drop_caches [-m] /mnt/lustre/file0 /mnt/lustre2/file0\n"
30 " -m : use mmap to read/write file\n", __func__);
33 #define handle_error(msg) \
34 do { perror(msg); exit(EXIT_FAILURE); } while (0)
36 static int fd[2] = { -1, -1 };
37 /* u_max is total number of writes, which are time consumg because they are
38 * contending with constant reads
40 static uint64_t u, u_max = UINT64_MAX / 2;
43 #ifdef HAVE_LIBPTHREAD
46 static void *access_thread_start(void *unused)
53 ptr2 = mmap(NULL, sizeof(v[1]), PROT_READ,
54 MAP_PRIVATE | MAP_POPULATE, fd[1], 0);
55 if (ptr2 == MAP_FAILED)
60 for (i = 0; i < 2; i++) {
62 memcpy(&v[i], i == 0 ? ptr : ptr2,
65 rc = pread(fd[i], &v[i], sizeof(v[i]), 0);
66 if (rc < 0 || rc != sizeof(v[i]))
67 handle_error("pread");
70 } while (v[0] <= v[1]);
72 fprintf(stderr, "error: u = %"PRIu64", v = %"PRIu64", %"PRIu64"\n",
76 munmap(ptr2, sizeof(v[i]));
81 static char stderr_buf[4096];
83 int main(int argc, char *argv[])
85 int drop_caches_fd = -1;
86 pthread_t access_thread __attribute__ ((unused));
91 setvbuf(stderr, stderr_buf, _IOLBF, sizeof(stderr_buf));
93 while ((ch = getopt(argc, argv, "m")) >= 0) {
112 drop_caches_fd = open("/proc/sys/vm/drop_caches", O_WRONLY);
113 assert(!(drop_caches_fd < 0));
115 for (i = 0; i < 2; i++) {
116 fd[i] = open(argv[i], O_RDWR|O_CREAT|O_TRUNC, 0666);
118 handle_error("open");
120 rc = fstat(fd[i], &st[i]);
122 handle_error("fstat");
125 /* file0 and file1 should be the same file on two different
126 * client mount points. */
127 if (st[0].st_dev != st[1].st_dev ||
128 st[0].st_ino != st[1].st_ino) {
129 fprintf(stderr, "file mismatch\n");
134 if (ftruncate(fd[0], sizeof(u)) < 0)
135 handle_error("ftruncate");
137 ptr = mmap(NULL, sizeof(u), PROT_READ|PROT_WRITE, MAP_SHARED,
139 if (ptr == MAP_FAILED)
140 handle_error("mmap");
141 memcpy(ptr, &u, sizeof(u));
143 rc = pwrite(fd[0], &u, sizeof(u), 0);
144 if (rc < 0 || rc != sizeof(u))
145 handle_error("pwrite");
148 #ifdef HAVE_LIBPTHREAD
149 rc = pthread_create(&access_thread, NULL, &access_thread_start, NULL);
151 handle_error("pthread_create");
154 for (u = 1; u <= u_max; u++) {
156 memcpy(ptr, &u, sizeof(u));
158 rc = pwrite(fd[0], &u, sizeof(u), 0);
159 if (rc < 0 || rc != sizeof(u))
160 handle_error("pwrite");
163 rc = write(drop_caches_fd, "3\n", 2);
164 if (rc < 0 || rc != 2)
165 handle_error("drop caches");
168 #ifdef HAVE_LIBPTHREAD
169 rc = pthread_cancel(access_thread);
171 handle_error("pthread_cancel");
173 rc = pthread_join(access_thread, NULL);
175 handle_error("pthread_join");
179 munmap(ptr, sizeof(u));