master
c 120 lines 2.85 KB
Raw
1 #include <errno.h>
2 #include <string.h>
3 #include <stdio.h>
4 #include <sys/stat.h>
5 #include <sys/types.h>
6 #include <sys/mman.h>
7 #include <sys/types.h>
8
9 #define _GNU_SOURCE /* See feature_test_macros(7) */
10 #define __USE_GNU
11 #include <fcntl.h>
12 #include <unistd.h>
13
14 void test_sync_file_range(char *output, char *text, size_t length)
15 {
16 int fd = open (output, O_WRONLY | O_CREAT | O_APPEND, 0660);
17 if (fd < 0 ) {
18 perror("Cannot get page size");
19 return;
20 }
21
22 int i;
23 size_t offset = 0;
24 for ( i = 0 ; i < 10000; i++ ) {
25 write(fd, text, length);
26 sync_file_range(fd, offset, length, SYNC_FILE_RANGE_WRITE);
27 offset += length;
28 }
29
30 close(fd);
31 sleep(5);
32 }
33
34 // test based on IBM example https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_71/apis/msync.htm
35 void test_msync(char *output, char *text, size_t length)
36 {
37 int pagesize = sysconf(_SC_PAGE_SIZE);
38 if (pagesize < 0) {
39 perror("Cannot get page size");
40 return;
41 }
42
43 int fd = open(output, (O_CREAT | O_TRUNC | O_RDWR), (S_IRWXU | S_IRWXG | S_IRWXO));
44 if (fd < 0 ) {
45 perror("Cannot open file");
46 return;
47 }
48
49 off_t lastoffset = lseek( fd, pagesize, SEEK_SET);
50 ssize_t written = write(fd, " ", 1);
51 if ( written != 1 ) {
52 perror("Write error. ");
53 close(fd);
54 return;
55 }
56
57 off_t my_offset = 0;
58 void *address = mmap(NULL, pagesize, PROT_WRITE, MAP_SHARED, fd, my_offset);
59
60 if ( address == MAP_FAILED ) {
61 perror("Map error. ");
62 close(fd);
63 return;
64 }
65
66 (void) strcpy( (char*) address, text);
67
68 if ( msync( address, pagesize, MS_SYNC) < 0 ) {
69 perror("msync failed with error:");
70 }
71
72 close(fd);
73 sleep(5);
74 }
75
76 void test_synchronization(char *output, char *text, size_t length, int (*fcnt)(int))
77 {
78 int fd = open (output, O_WRONLY | O_CREAT | O_APPEND, 0660);
79 if (fd < 0 ) {
80 perror("Cannot get page size");
81 return;
82 }
83
84 int i;
85 for ( i = 0 ; i < 10000; i++ )
86 write(fd, text, length);
87
88 fcnt(fd);
89 close(fd);
90
91 sleep(5);
92 }
93
94 void remove_files(char **files) {
95 size_t i = 0;
96 while (files[i]) {
97 unlink(files[i]);
98 i++;
99 }
100 }
101
102 int main()
103 {
104 char *default_text = { "This is a simple example to test a PR. The sleep is used to create different peaks on charts.\n" };
105 char *files[] = { "fsync.txt", "fdatasync.txt", "syncfs.txt", "msync.txt", "sync_file_range.txt", NULL };
106 size_t length = strlen(default_text);
107 test_synchronization(files[0], default_text, length, fsync);
108 test_synchronization(files[1], default_text, length, fdatasync);
109 test_synchronization(files[2], default_text, length, syncfs);
110
111 test_msync(files[3], default_text, length);
112
113 test_sync_file_range(files[4], default_text, length);
114
115 sync();
116
117 remove_files(files);
118
119 return 0;
120 }