Hi team! As previously discussed with Michael Vogt on #debian-apt, I've done some investigation about mmap() and related, and I have following results: 1) mmap() call actually doesn't map whole memory (mmap() has successfully mmap'ed 23 GiB, of course I have no such amounts of memory on my desktop); process memory are untouched at all; 2) mmap() call doesn't grow a file attached to it, file size stays untouched directly after mmap(); 3) when writing to mmap'ed region, file size become maximum of offsets that were used for writing. These investigations incited me to wonder if we... can simply do mmap(2GiB -1) amount of memory, without any troubles?! I have attached C source file, use "gcc -std=gnu99 -Wall -O2 -Wextra bigmmap.c -o bigmmap" to compile it. Please confirm my results... -- Eugene V. Lyubimkin aka JackYF, Ukrainian C++ developer.
#define _LARGEFILE64_SOURCE #include <stdio.h> #include <stdlib.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> int main(int argc, char* argv[]) { if (argc != 2) { printf("One parameter (number of pages to mmap) required.\n"); return 1; } int page_size = sysconf(_SC_PAGE_SIZE); unsigned long mmap_size = atol(argv[1]) * page_size; printf("Mapping %zd MiB.\n", mmap_size / 1024 / 1024); const char filename[] = "binfile"; int fd = open(filename, O_CREAT | O_RDWR); if (fd == -1) { printf("Cannot open %s.\n", filename); return 2; } /* lseek64(fd, mmap_size-1, SEEK_SET); write(fd, "\0", 1); lseek64(fd, 0, SEEK_SET); */ void* base = mmap(NULL, mmap_size, PROT_WRITE | PROT_WRITE, MAP_SHARED, fd, 0); if (base == MAP_FAILED) { printf("Cannot mmap :-(\n"); return 3; } printf("Bound address: %p\n", base); // main loop size_t mpos = -1; size_t step = 2; for (size_t i = 0; i < mmap_size/page_size; i += step) { usleep(50); off_t offset = lseek64(fd, page_size*step, SEEK_CUR); write(fd, "\0", 1); size_t newpos = offset/1024/1024; if (mpos != newpos) { printf("\rNow at %zd MiB...", newpos); fflush(stdout); mpos = newpos; } } munmap(base, mmap_size); close(fd); printf("Done\n"); return 0; }
Attachment:
signature.asc
Description: OpenPGP digital signature