-
Notifications
You must be signed in to change notification settings - Fork 3
/
test-mmap-sync.c
145 lines (129 loc) · 2.9 KB
/
test-mmap-sync.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#define _GNU_SOURCE
#include <sys/mman.h>
#include <fcntl.h>
#include <pthread.h>
#include <errno.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static int file_fd;
static uint64_t filesize = 1024 * 1024 * 1024;
static uint64_t bs = 128 * 1024 * 1024;
static int nr_threads = 3;
static int loops = 100000;
#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
#define MAX(x, a) ((x) < (a) ? a : x)
#define MIN(x, a) ((x) < (a) ? x : a)
static void get_offset_size(uint64_t *offset, uint64_t *size)
{
*size = (uint64_t)random() % filesize;
*offset = (uint64_t)random() % filesize;
*offset = MIN(ALIGN(*offset, bs), filesize - bs);
*size = MAX(ALIGN(*size, bs), bs);
*size = MIN(*size, filesize - *offset);
}
static void *sync_file(void *arg)
{
int i, ret;
for (i = 0; i < loops; i++) {
ret = sync_file_range(file_fd, 0, filesize,
SYNC_FILE_RANGE_WRITE);
if (ret) {
perror("Couldn't sync");
break;
}
sleep(2);
}
return NULL;
}
static void *mwrite_file(void *arg)
{
char fill = random();
char *ptr = mmap(NULL, filesize, PROT_WRITE, MAP_SHARED, file_fd, 0);
uint64_t offset = 0;
int i;
if (ptr == MAP_FAILED) {
perror("Mmap failed");
return NULL;
}
for (i = 0; i < loops; i++) {
for (offset = bs; offset < filesize; offset += bs) {
uint64_t off = offset - (1024 * 1024);
uint64_t size = 2 * 1024 * 1024;
memset(ptr + off, fill, size);
}
}
return NULL;
}
static void *write_file(void *arg)
{
char fill = random();
char *buf;
ssize_t ret;
uint64_t offset;
int i;
buf = malloc(bs);
if (!buf) {
perror("Couldn't allocate temporary buffer");
return NULL;
}
memset(buf, fill, bs);
for (i = 0; i < loops; i++) {
for (offset = 0; offset < filesize; offset += bs) {
ret = pwrite(file_fd, buf, bs, offset);
if (ret < 0) {
perror("Failed to write fd");
goto out;
}
}
}
out:
free(buf);
return NULL;
}
int main(int argc, char **argv)
{
pthread_t *threads;
int i, ret;
file_fd = open("testfile", O_CREAT|O_RDWR|O_TRUNC, 0644);
if (file_fd < 0) {
perror("Failed to open file_fd");
return -1;
}
if (ftruncate(file_fd, filesize)) {
perror("Ftruncate failed");
return -1;
}
threads = malloc(sizeof(pthread_t) * nr_threads);
if (!threads) {
perror("Couldn't allocate threads array");
return -1;
}
memset(threads, 0, sizeof(pthread_t) * nr_threads);
for (i = 0; i < nr_threads - 1; i++) {
if (i % 2)
ret = pthread_create(&threads[i], NULL, write_file, NULL);
else
ret = pthread_create(&threads[i], NULL, mwrite_file, NULL);
if (ret) {
perror("Failed to create thread");
goto out;
}
}
ret = pthread_create(&threads[nr_threads - 1], NULL, sync_file, NULL);
if (ret) {
perror("Failed to create sync thread");
goto out;
}
out:
for (i = 0; i < nr_threads; i++) {
ret = pthread_join(threads[i], NULL);
if (ret) {
perror("Couldn't pthread_join");
return -1;
}
}
return 0;
}