Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/openzfs/tests/zfs-tests/cmd/mmap_sync.c
48529 views
1
// SPDX-License-Identifier: CDDL-1.0
2
/*
3
* CDDL HEADER START
4
*
5
* The contents of this file are subject to the terms of the
6
* Common Development and Distribution License (the "License").
7
* You may not use this file except in compliance with the License.
8
*
9
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10
* or http://opensource.org/licenses/CDDL-1.0.
11
* See the License for the specific language governing permissions
12
* and limitations under the License.
13
*
14
* When distributing Covered Code, include this CDDL HEADER in each
15
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16
* If applicable, add the following below this CDDL HEADER, with the
17
* fields enclosed by brackets "[]" replaced with your own identifying
18
* information: Portions Copyright [yyyy] [name of copyright owner]
19
*
20
* CDDL HEADER END
21
*/
22
23
#include <stdlib.h>
24
#include <stdio.h>
25
#include <string.h>
26
#include <sys/mman.h>
27
#include <sys/stat.h>
28
#include <sys/time.h>
29
#include <fcntl.h>
30
#include <unistd.h>
31
#include <time.h>
32
33
static void
34
cleanup(char *file)
35
{
36
(void) remove(file);
37
}
38
39
int
40
main(int argc, char *argv[])
41
{
42
char *testdir = getenv("TESTDIR");
43
if (!testdir) {
44
fprintf(stderr, "environment variable TESTDIR not set\n");
45
return (1);
46
}
47
48
struct stat st;
49
umask(0);
50
if (stat(testdir, &st) != 0 &&
51
mkdir(testdir, 0777) != 0) {
52
perror("mkdir");
53
return (1);
54
}
55
56
if (argc > 3) {
57
fprintf(stderr, "usage: %s "
58
"[run time in mins] "
59
"[max msync time in ms]\n", argv[0]);
60
return (1);
61
}
62
63
int run_time_mins = 1;
64
if (argc >= 2) {
65
run_time_mins = atoi(argv[1]);
66
}
67
68
int max_msync_time_ms = 2000;
69
if (argc >= 3) {
70
max_msync_time_ms = atoi(argv[2]);
71
}
72
73
char filepath[512];
74
filepath[0] = '\0';
75
char *file = &filepath[0];
76
77
(void) snprintf(file, 512, "%s/msync_file", testdir);
78
79
const int LEN = 8;
80
cleanup(file);
81
82
int fd = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR |
83
S_IRGRP | S_IROTH);
84
85
if (fd == -1) {
86
(void) fprintf(stderr, "%s: %s: ", argv[0], file);
87
perror("open");
88
return (1);
89
}
90
91
if (ftruncate(fd, LEN) != 0) {
92
perror("ftruncate");
93
cleanup(file);
94
return (1);
95
}
96
97
void *ptr = mmap(NULL, LEN, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
98
99
if (ptr == MAP_FAILED) {
100
perror("mmap");
101
cleanup(file);
102
return (1);
103
}
104
105
struct timeval tstart;
106
gettimeofday(&tstart, NULL);
107
108
long long x = 0LL;
109
110
for (;;) {
111
*((long long *)ptr) = x;
112
x++;
113
114
struct timeval t1, t2;
115
gettimeofday(&t1, NULL);
116
if (msync(ptr, LEN, MS_SYNC|MS_INVALIDATE) != 0) {
117
perror("msync");
118
cleanup(file);
119
return (1);
120
}
121
122
gettimeofday(&t2, NULL);
123
124
double elapsed = (t2.tv_sec - t1.tv_sec) * 1000.0;
125
elapsed += ((t2.tv_usec - t1.tv_usec) / 1000.0);
126
if (elapsed > max_msync_time_ms) {
127
fprintf(stderr, "slow msync: %f ms\n", elapsed);
128
if (munmap(ptr, LEN) != 0)
129
perror("munmap");
130
cleanup(file);
131
return (1);
132
}
133
134
double elapsed_start = (t2.tv_sec - tstart.tv_sec) * 1000.0;
135
elapsed_start += ((t2.tv_usec - tstart.tv_usec) / 1000.0);
136
if (elapsed_start > run_time_mins * 60 * 1000) {
137
break;
138
}
139
}
140
141
if (munmap(ptr, LEN) != 0) {
142
perror("munmap");
143
cleanup(file);
144
return (1);
145
}
146
147
if (close(fd) != 0) {
148
perror("close");
149
}
150
151
cleanup(file);
152
return (0);
153
}
154
155