bzr branch
http://darksoft.org/webbzr/alps/fwbench
8
by Suren A. Chilingaryan
Support RAW devices by seqreader |
1 |
#define _GNU_SOURCE
|
2 |
||
7
by Suren A. Chilingaryan
seqreader |
3 |
#include <stdio.h> |
4 |
#include <stdlib.h> |
|
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
5 |
#include <stdint.h> |
7
by Suren A. Chilingaryan
seqreader |
6 |
#include <sys/types.h> |
7 |
#include <sys/stat.h> |
|
8 |
#include <sys/time.h> |
|
9 |
#include <unistd.h> |
|
10 |
#include <dirent.h> |
|
8
by Suren A. Chilingaryan
Support RAW devices by seqreader |
11 |
#include <fcntl.h> |
12 |
#include <string.h> |
|
13 |
#include <errno.h> |
|
14 |
||
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
15 |
#include <libaio.h> |
16 |
||
11
by Suren A. Chilingaryan
Use O_DIRECT mode in seqreader |
17 |
#define FASTWRITER_SYNCIO_ALIGN 512
|
18 |
||
12
by Suren A. Chilingaryan
fsbench |
19 |
#define SYNC_MODE
|
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
20 |
#define AIO_MODE 2
|
15
by Suren A. Chilingaryan
Better directory mode in seqreader |
21 |
//#define FS_SYNC_MODE
|
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
22 |
#define EXTRA_BUFFERS 2
|
23 |
#define WRITE_INTERVAL 1
|
|
24 |
||
17
by Suren A. Chilingaryan
Big file support |
25 |
|
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
26 |
#define RAID_STRIP_SIZE 256
|
27 |
#define RAID_DISKS 8
|
|
28 |
#define STRIPS_AT_ONCE 2
|
|
29 |
||
17
by Suren A. Chilingaryan
Big file support |
30 |
#define FS_MIN_BLOCK_SIZE (1024 * RAID_STRIP_SIZE)
|
31 |
#define FS_BLOCK_SIZE (1024 * RAID_STRIP_SIZE * RAID_DISKS)
|
|
32 |
||
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
33 |
#ifdef AIO_MODE
|
34 |
# define SYNC_MODE
|
|
35 |
#endif /* AIO_MODE */ |
|
36 |
||
12
by Suren A. Chilingaryan
fsbench |
37 |
#ifdef SYNC_MODE
|
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
38 |
# define BLOCK_SIZE (1024 * RAID_STRIP_SIZE * RAID_DISKS * STRIPS_AT_ONCE)
|
12
by Suren A. Chilingaryan
fsbench |
39 |
#else /* SYNC_MODE */ |
40 |
# define BLOCK_SIZE 16384
|
|
41 |
#endif /* SYNC_MODE */ |
|
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
42 |
|
43 |
#ifdef AIO_MODE
|
|
44 |
# define BUFSIZE (BLOCK_SIZE * (AIO_MODE + EXTRA_BUFFERS))
|
|
45 |
#else /* AIO_MODE */ |
|
19
by Suren A. Chilingaryan
Fix segmentation in seqreader |
46 |
# define BUFSIZE (1024 * RAID_STRIP_SIZE * RAID_DISKS * STRIPS_AT_ONCE)
|
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
47 |
#endif /* AIO_MODE */ |
8
by Suren A. Chilingaryan
Support RAW devices by seqreader |
48 |
|
7
by Suren A. Chilingaryan
seqreader |
49 |
|
50 |
int main(int argc, char *argv[]) { |
|
51 |
int err; |
|
52 |
size_t SKIP = 1; |
|
53 |
DIR *dir; |
|
54 |
struct dirent *ent; |
|
15
by Suren A. Chilingaryan
Better directory mode in seqreader |
55 |
struct timeval start, fstart, tv; |
7
by Suren A. Chilingaryan
seqreader |
56 |
size_t us; |
57 |
size_t files = 0; |
|
58 |
size_t total_size = 0; |
|
8
by Suren A. Chilingaryan
Support RAW devices by seqreader |
59 |
size_t last_write = 0; |
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
60 |
size_t last_size = 0; |
7
by Suren A. Chilingaryan
seqreader |
61 |
size_t skip; |
62 |
size_t run; |
|
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
63 |
size_t ready; |
9
by Suren A. Chilingaryan
Report speed in seqreader using proper MB/s |
64 |
ssize_t res; |
12
by Suren A. Chilingaryan
fsbench |
65 |
size_t max_size = (size_t)-1; |
15
by Suren A. Chilingaryan
Better directory mode in seqreader |
66 |
char *buffer; |
9
by Suren A. Chilingaryan
Report speed in seqreader using proper MB/s |
67 |
long double mcoef = 1000000. / (1024 * 1024); |
12
by Suren A. Chilingaryan
fsbench |
68 |
int flags = O_RDONLY|O_NOATIME|O_LARGEFILE; |
17
by Suren A. Chilingaryan
Big file support |
69 |
struct stat st; |
12
by Suren A. Chilingaryan
fsbench |
70 |
|
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
71 |
#ifdef AIO_MODE
|
72 |
int i; |
|
73 |
size_t curio, schedio; |
|
74 |
int done[AIO_MODE + EXTRA_BUFFERS]; |
|
75 |
||
76 |
io_context_t aio; |
|
77 |
struct iocb io[AIO_MODE], *ioptr[AIO_MODE]; |
|
78 |
||
79 |
int events; |
|
80 |
struct io_event ev[AIO_MODE]; |
|
81 |
#endif /* AIO_MODE */ |
|
82 |
||
83 |
||
11
by Suren A. Chilingaryan
Use O_DIRECT mode in seqreader |
84 |
posix_memalign((void**)&buffer, FASTWRITER_SYNCIO_ALIGN, BUFSIZE); |
85 |
||
7
by Suren A. Chilingaryan
seqreader |
86 |
if (argc < 2) { |
17
by Suren A. Chilingaryan
Big file support |
87 |
printf("Usage: %s <directory|file|device> [skip|size]\n", argv[0]); |
7
by Suren A. Chilingaryan
seqreader |
88 |
exit(0); |
89 |
}
|
|
90 |
||
17
by Suren A. Chilingaryan
Big file support |
91 |
if (stat(argv[1], &st)) { |
92 |
printf("stat on (%s) have failed", argv[1]); |
|
93 |
exit(-1); |
|
94 |
}
|
|
95 |
||
96 |
if (strstr(argv[1], "/dev/")||(S_ISREG(st.st_mode))) { |
|
12
by Suren A. Chilingaryan
fsbench |
97 |
if (argc > 2) { |
98 |
max_size = atol(argv[2]); |
|
99 |
max_size *= 1024 * 1024 * 1024; |
|
100 |
}
|
|
101 |
||
15
by Suren A. Chilingaryan
Better directory mode in seqreader |
102 |
#ifdef SYNC_MODE
|
103 |
flags |= O_DIRECT; |
|
104 |
#endif
|
|
105 |
||
106 |
printf("Used buffer: %i MB, Block: %i KB\n", BUFSIZE / 1024 / 1024, BLOCK_SIZE/1024); |
|
107 |
||
108 |
||
12
by Suren A. Chilingaryan
fsbench |
109 |
int fd = open(argv[1], flags, 0); |
8
by Suren A. Chilingaryan
Support RAW devices by seqreader |
110 |
if (fd < 0) { |
111 |
printf("Unable to open device %s\n", argv[1]); |
|
112 |
exit(1); |
|
113 |
}
|
|
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
114 |
|
9
by Suren A. Chilingaryan
Report speed in seqreader using proper MB/s |
115 |
size_t size = BLOCK_SIZE; |
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
116 |
|
117 |
#ifdef AIO_MODE
|
|
118 |
memset(done, 0, sizeof(done)); |
|
119 |
memset(&aio, 0, sizeof(aio)); |
|
120 |
io_queue_init(AIO_MODE, &aio); |
|
121 |
for (i = 0; i < AIO_MODE; i++) { |
|
122 |
ioptr[i] = &io[i]; |
|
123 |
memset(ioptr[i], 0, sizeof(struct iocb)); |
|
124 |
io_prep_pread(ioptr[i], fd, buffer + i * BLOCK_SIZE, BLOCK_SIZE, i * BLOCK_SIZE); |
|
125 |
io_set_callback(ioptr[i], (void*)(uintptr_t)i); |
|
126 |
}
|
|
127 |
||
128 |
curio = 0; |
|
129 |
schedio = AIO_MODE; |
|
130 |
events = 0; |
|
131 |
#endif /* AIO_MODE */ |
|
8
by Suren A. Chilingaryan
Support RAW devices by seqreader |
132 |
|
133 |
gettimeofday(&start, NULL); |
|
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
134 |
|
135 |
#ifdef AIO_MODE
|
|
136 |
err = io_submit(aio, AIO_MODE, ioptr); |
|
137 |
if (err != AIO_MODE) { |
|
17
by Suren A. Chilingaryan
Big file support |
138 |
printf("Failed to submit initial AIO job, io_submit returned %i\n", err); |
139 |
exit(-1); |
|
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
140 |
}
|
141 |
#endif /* AIO_MODE */ |
|
142 |
||
143 |
#ifdef AIO_MODE
|
|
144 |
ready = 0; |
|
145 |
while (1) { |
|
146 |
if (!done[curio%(AIO_MODE + EXTRA_BUFFERS)]) { |
|
16
by Suren A. Chilingaryan
Fixes bugs in AIO mode |
147 |
// printf("%i,%i - %i [%i %i %i %i]\n", curio, schedio, events, done[0], done[1], done[2], done[3]);
|
148 |
||
149 |
if (curio < schedio) { |
|
150 |
err = io_getevents(aio, 1, AIO_MODE + EXTRA_BUFFERS - events, &ev[events], NULL); |
|
151 |
if (err < 0) { |
|
152 |
printf("Error waiting for AIO (%i)\n", -err); |
|
153 |
exit(-1); |
|
154 |
}
|
|
155 |
} else { |
|
156 |
err = 0; |
|
157 |
}
|
|
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
158 |
|
159 |
if ((!ready)&&(err > 1)) { |
|
160 |
printf("*** Multiple read requests (%i of %i) are finished simultaneously. It is either:\n", err, AIO_MODE); |
|
161 |
printf(" Small buffer size (%i KB)\n", BLOCK_SIZE/1024); |
|
162 |
printf(" More parallel AIOs (%i) than supported by kernel, try %i\n", AIO_MODE, AIO_MODE - err); |
|
163 |
}
|
|
164 |
||
165 |
for (i = 0; i < err; i++) { |
|
166 |
struct io_event *ep = &ev[events + i]; |
|
167 |
int doneio = (uintptr_t)ep->data; |
|
17
by Suren A. Chilingaryan
Big file support |
168 |
if (ep->res2 || (ep->res != BLOCK_SIZE)) { |
169 |
printf("Error in async IO\n"); |
|
170 |
exit(-1); |
|
171 |
}
|
|
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
172 |
done[doneio%(AIO_MODE + EXTRA_BUFFERS)] = 1; |
173 |
// printf("done (%i): %i\n", i, doneio);
|
|
174 |
}
|
|
175 |
||
176 |
events += err; |
|
177 |
||
178 |
for (i = events - 1; (i >= 0)&&((schedio - curio) < (AIO_MODE + EXTRA_BUFFERS)); i--) { |
|
16
by Suren A. Chilingaryan
Fixes bugs in AIO mode |
179 |
// printf("sched (%i): %i\n", i, schedio);
|
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
180 |
struct iocb *newio = (struct iocb *)ev[i].obj; |
181 |
memset(newio, 0, sizeof(struct iocb)); |
|
182 |
io_prep_pread(newio, fd, buffer + (schedio % (AIO_MODE + EXTRA_BUFFERS)) * BLOCK_SIZE, BLOCK_SIZE, schedio * BLOCK_SIZE); |
|
183 |
io_set_callback(newio, (void*)(uintptr_t)schedio); |
|
184 |
err = io_submit(aio, 1, &newio); |
|
17
by Suren A. Chilingaryan
Big file support |
185 |
if (err != 1) { |
186 |
printf("Failed to submit AIO jobs %i", err); |
|
187 |
exit(-1); |
|
188 |
}
|
|
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
189 |
schedio++; |
190 |
}
|
|
191 |
events = i + 1; |
|
192 |
||
193 |
if (events) { |
|
194 |
printf("*** Unprocessed events (%i), probably not enough buffer space...\n", events); |
|
195 |
// printf(" curio (%zu), schedio (%zu)\n", curio, schedio);
|
|
196 |
}
|
|
197 |
||
198 |
ready = 1; |
|
199 |
continue; |
|
200 |
}
|
|
201 |
||
202 |
done[curio%(AIO_MODE + EXTRA_BUFFERS)] = 0; |
|
203 |
curio++; |
|
204 |
||
205 |
res = BLOCK_SIZE; |
|
206 |
#else /* AIO_MODE */ |
|
9
by Suren A. Chilingaryan
Report speed in seqreader using proper MB/s |
207 |
res = read(fd, buffer, size); |
208 |
while (res > 0) { |
|
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
209 |
#endif /* AIO_MODE */ |
210 |
||
9
by Suren A. Chilingaryan
Report speed in seqreader using proper MB/s |
211 |
if (res != size) { |
212 |
printf("Incomplete read: %zu bytes read instead of %zu\n", res, size); |
|
213 |
exit(-1); |
|
214 |
}
|
|
215 |
total_size += res; |
|
8
by Suren A. Chilingaryan
Support RAW devices by seqreader |
216 |
|
217 |
gettimeofday(&tv, NULL); |
|
218 |
us = (tv.tv_sec - start.tv_sec) * 1000000 + (tv.tv_usec - start.tv_usec); |
|
219 |
if ((us - last_write) > WRITE_INTERVAL * 1000000) { |
|
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
220 |
printf("Reading: %s (%lu GB), Measured speed: %zu MB/s, Current speed: %zu MB/s\n", argv[0], total_size / 1024 / 1024 / 1024, (size_t)(mcoef * total_size / us), (size_t)(mcoef * (total_size - last_size) / (us - last_write))); |
8
by Suren A. Chilingaryan
Support RAW devices by seqreader |
221 |
last_write = us; |
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
222 |
last_size = total_size; |
8
by Suren A. Chilingaryan
Support RAW devices by seqreader |
223 |
}
|
12
by Suren A. Chilingaryan
fsbench |
224 |
|
225 |
if (total_size > max_size) { |
|
226 |
printf("Reading: %s (%lu GB), Measured speed: %zu MB/s\n", argv[0], total_size / 1024 / 1024 / 1024, (size_t)(mcoef * total_size / us)); |
|
227 |
break; |
|
228 |
}
|
|
229 |
||
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
230 |
#ifndef AIO_MODE
|
9
by Suren A. Chilingaryan
Report speed in seqreader using proper MB/s |
231 |
res = read(fd, buffer, size); |
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
232 |
#endif /* AIO_MODE */ |
8
by Suren A. Chilingaryan
Support RAW devices by seqreader |
233 |
}
|
234 |
||
13
by Suren A. Chilingaryan
Use kernel asynchronous i/o in seqreader |
235 |
#ifdef AIO_MODE
|
236 |
io_queue_release(aio); |
|
237 |
#endif /* AIO_MODE */ |
|
238 |
||
8
by Suren A. Chilingaryan
Support RAW devices by seqreader |
239 |
close(fd); |
240 |
||
9
by Suren A. Chilingaryan
Report speed in seqreader using proper MB/s |
241 |
if (res < 0) { |
242 |
printf("Read failed with errno %i\n", errno); |
|
243 |
exit(-1); |
|
244 |
}
|
|
8
by Suren A. Chilingaryan
Support RAW devices by seqreader |
245 |
|
11
by Suren A. Chilingaryan
Use O_DIRECT mode in seqreader |
246 |
free(buffer); |
247 |
||
8
by Suren A. Chilingaryan
Support RAW devices by seqreader |
248 |
return 0; |
249 |
}
|
|
250 |
||
15
by Suren A. Chilingaryan
Better directory mode in seqreader |
251 |
#ifdef FS_SYNC_MODE
|
252 |
flags |= O_DIRECT; |
|
253 |
#endif /* FS_SYNC_MODE */ |
|
254 |
||
7
by Suren A. Chilingaryan
seqreader |
255 |
chdir(argv[1]); |
256 |
||
257 |
if (argc > 2) { |
|
258 |
SKIP = atoi(argv[2]); |
|
259 |
||
8
by Suren A. Chilingaryan
Support RAW devices by seqreader |
260 |
printf("Skip %zu\n", SKIP); |
7
by Suren A. Chilingaryan
seqreader |
261 |
}
|
262 |
||
263 |
gettimeofday(&start, NULL); |
|
264 |
for (run = 0; run < SKIP; run++) { |
|
265 |
skip = 0; |
|
266 |
dir = opendir("."); |
|
8
by Suren A. Chilingaryan
Support RAW devices by seqreader |
267 |
while ((ent = readdir(dir))) { |
7
by Suren A. Chilingaryan
seqreader |
268 |
if (((skip++)%SKIP) != run) continue; |
269 |
||
270 |
if (stat(ent->d_name, &st)) continue; |
|
271 |
if (!S_ISREG(st.st_mode)) continue; |
|
12
by Suren A. Chilingaryan
fsbench |
272 |
|
15
by Suren A. Chilingaryan
Better directory mode in seqreader |
273 |
int size = st.st_blksize; |
274 |
||
12
by Suren A. Chilingaryan
fsbench |
275 |
#ifdef F_MODE
|
7
by Suren A. Chilingaryan
seqreader |
276 |
FILE *f = fopen(ent->d_name, "r"); |
277 |
if (!f) continue; |
|
12
by Suren A. Chilingaryan
fsbench |
278 |
#else
|
279 |
int fd = open(ent->d_name, flags, 0); |
|
280 |
if (fd < 0) continue; |
|
15
by Suren A. Chilingaryan
Better directory mode in seqreader |
281 |
|
282 |
# ifdef FS_SYNC_MODE
|
|
283 |
if (size < BLOCK_SIZE) size = BLOCK_SIZE; |
|
284 |
# endif /* FS_SYNC_MODE */ |
|
17
by Suren A. Chilingaryan
Big file support |
285 |
if (size < FS_MIN_BLOCK_SIZE) size = FS_BLOCK_SIZE; |
12
by Suren A. Chilingaryan
fsbench |
286 |
#endif
|
15
by Suren A. Chilingaryan
Better directory mode in seqreader |
287 |
|
288 |
if (!files) |
|
289 |
printf("Reading %s, Block: %i KB\n", ent->d_name, size / 1024); |
|
7
by Suren A. Chilingaryan
seqreader |
290 |
|
291 |
if (size > BUFSIZE) { |
|
292 |
printf("Buffer too small\n"); |
|
293 |
exit(1); |
|
294 |
}
|
|
12
by Suren A. Chilingaryan
fsbench |
295 |
|
15
by Suren A. Chilingaryan
Better directory mode in seqreader |
296 |
size_t last_file_write = 0; |
297 |
size_t last_file_size = 0; |
|
298 |
size_t file_size = 0; |
|
299 |
gettimeofday(&fstart, NULL); |
|
12
by Suren A. Chilingaryan
fsbench |
300 |
|
301 |
#ifdef F_MODE
|
|
7
by Suren A. Chilingaryan
seqreader |
302 |
while (!feof(f)) { |
15
by Suren A. Chilingaryan
Better directory mode in seqreader |
303 |
ssize_t ret = fread(buffer, 1, size, f); |
12
by Suren A. Chilingaryan
fsbench |
304 |
#else
|
15
by Suren A. Chilingaryan
Better directory mode in seqreader |
305 |
while (1) { |
306 |
ssize_t ret = read(fd, buffer, size); |
|
12
by Suren A. Chilingaryan
fsbench |
307 |
#endif
|
15
by Suren A. Chilingaryan
Better directory mode in seqreader |
308 |
if (ret <= 0) break; |
309 |
||
310 |
file_size += ret; |
|
311 |
||
312 |
gettimeofday(&tv, NULL); |
|
313 |
us = (tv.tv_sec - fstart.tv_sec) * 1000000 + (tv.tv_usec - fstart.tv_usec); |
|
314 |
||
315 |
if ((us - last_file_write) > WRITE_INTERVAL * 1000000) { |
|
316 |
printf("Reading: %s (%lu GB), Measured speed: %zu MB/s, Current speed: %zu MB/s\n", ent->d_name, file_size / 1024 / 1024 / 1024, (size_t)(mcoef * file_size / us), (size_t)(mcoef * (file_size - last_file_size) / (us - last_file_write))); |
|
317 |
last_file_write = us; |
|
318 |
last_file_size = file_size; |
|
319 |
}
|
|
320 |
}
|
|
321 |
||
322 |
if (!file_size) { |
|
12
by Suren A. Chilingaryan
fsbench |
323 |
printf("Read failed\n"); |
324 |
exit(1); |
|
325 |
}
|
|
326 |
||
327 |
#ifdef F_MODE
|
|
7
by Suren A. Chilingaryan
seqreader |
328 |
fclose(f); |
12
by Suren A. Chilingaryan
fsbench |
329 |
#else
|
330 |
close(fd); |
|
331 |
#endif
|
|
7
by Suren A. Chilingaryan
seqreader |
332 |
|
333 |
total_size += st.st_size; |
|
334 |
files++; |
|
335 |
||
336 |
gettimeofday(&tv, NULL); |
|
337 |
us = (tv.tv_sec - start.tv_sec) * 1000000 + (tv.tv_usec - start.tv_usec); |
|
15
by Suren A. Chilingaryan
Better directory mode in seqreader |
338 |
if ((us - last_write) > WRITE_INTERVAL * 1000000) { |
339 |
last_write = us; |
|
340 |
printf("Read: %lu files (%lu GB) at %zu MB/s", files, total_size / 1024 / 1024 / 1024, (size_t)(mcoef * total_size / us)); |
|
341 |
||
342 |
us = (tv.tv_sec - fstart.tv_sec) * 1000000 + (tv.tv_usec - fstart.tv_usec); |
|
343 |
printf(", Last: %s (%lu MB) at %zu MB/s\n", ent->d_name, st.st_size/1024/1024, (size_t)(mcoef * file_size / us)); |
|
344 |
}
|
|
7
by Suren A. Chilingaryan
seqreader |
345 |
}
|
346 |
closedir(dir); |
|
15
by Suren A. Chilingaryan
Better directory mode in seqreader |
347 |
|
348 |
us = (tv.tv_sec - start.tv_sec) * 1000000 + (tv.tv_usec - start.tv_usec); |
|
349 |
printf("Total: %lu files (%lu GB) at %zu MB/s\n", files, total_size / 1024 / 1024 / 1024, (size_t)(mcoef * total_size / us)); |
|
7
by Suren A. Chilingaryan
seqreader |
350 |
}
|
11
by Suren A. Chilingaryan
Use O_DIRECT mode in seqreader |
351 |
|
352 |
free(buffer); |
|
7
by Suren A. Chilingaryan
seqreader |
353 |
|
354 |
}
|