Date: Wed, 9 Oct 2013 15:42:27 +0400 From: Dmitry Sivachenko <trtrmitya@gmail.com> To: "hackers@freebsd.org" <hackers@freebsd.org> Subject: mmap() question Message-ID: <95E0B821-BF9B-4EBF-A1E5-1DDCBB1C3D1B@gmail.com>
next in thread | raw e-mail | index | archive | help
Hello!
I have a program which mmap()s a lot of large files (total size more =
that RAM and I have no swap), but it needs only small parts of that =
files at a time.
My understanding is that when using mmap when I access some memory =
region OS reads the relevant portion of that file from disk and caches =
the result in memory. If there is no free memory, OS will purge =
previously read part of mmap'ed file to free memory for the new chunk.
But this is not the case. I use the following simple program which gets =
list of files as command line arguments, mmap()s them all and then =
selects random file and random 1K parts of that file and computes a XOR =
of bytes from that region.
After some time the program dies:
pid 63251 (a.out), uid 1232, was killed: out of swap space
It seems I incorrectly understand how mmap() works, can you please =
clarify what's going wrong?
I expect that program to run indefinitely, purging some regions out of =
RAM and reading the relevant parts of files.
Thanks!
#include <err.h>
#include <fcntl.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
struct f_data {
char *beg;
off_t size;
};
int
main(int argc, char* argv[]) {
if (argc < 2) {
fprintf(stderr, "Usage: %s <file> ...\n", argv[0]);
exit(0);
}
int i, j, fd;
struct stat st;
struct f_data FILES[500];
int NUM_FILES;
void *p;
NUM_FILES =3D argc - 1;
for (i=3D1; i < argc; i++) {
printf("%s... ", argv[i]);
if ((fd =3D open(argv[i], O_RDONLY)) < 0)
errx(1, "open");
if (fstat(fd, &st) !=3D 0)
errx(1, "fstat");
if ((p =3D mmap(NULL, st.st_size, PROT_READ, MAP_NOCORE, fd, 0)) =
=3D=3D MAP_FAILED)
errx(1, "mmap");
FILES[i-1].beg =3D (char*)p;
FILES[i-1].size =3D st.st_size;
if (msync(p, st.st_size, MS_INVALIDATE) !=3D 0)
errx(1, "msync");
printf("Ok.\n");
}
char chk =3D 0;
while(1) {
int rf =3D floor((double)random() / 2147483647 * NUM_FILES);
off_t offs =3D floor((double)random() / 2147483647 * =
(FILES[rf].size - 1024));
for (j=3D0; j<1024; j++)
chk ^=3D *(FILES[rf].beg + offs + j);
}
return 0;
}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?95E0B821-BF9B-4EBF-A1E5-1DDCBB1C3D1B>
