Subject: mmap
To: None <current-users@netbsd.org>
From: Andreas Wrede <andreas@planix.com>
List: current-users
Date: 11/09/1998 16:52:13
The configure script for the Cyrus imapd server ver 1.5.14 runs a test program
to "Verify the OS supports the memory mapping semantics needed by
map_private".
The program fails in different ways on both 1.3.2 and -current. On 1.3.2 it
results in "private map does not show change", while on -current it prints
"shared map does not match within page" (see code below).
I don't understand the intricacies of mmap well enough to see what is going
on, but the fact that there is a difference appears to indicate that we
have a problem here.
Both 1.3.2 and -current are i386, -current is 1.3H from Nov 4, using gcc
2.7.2.2, UVM and PMAP_NEW.
---[snip]---
/* Verify the OS supports the memory mapping semantics needed by map_private
* from John Myers <jgmyers@netscape.com>
*/
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
#ifndef MAP_NORESERVE
#define MAP_NORESERVE 0
#endif
/* not on Linux */
#ifndef MAP_VARIABLE
#define MAP_VARIABLE 0
#endif
#ifndef MAP_FAILED
#define MAP_FAILED ((void *) -1)
#endif
fatal(char *s)
{
write(2, s, strlen(s));
write(2, "\n", 1);
unlink("conftestmmap");
exit(1);
}
main() {
int fd = open("conftestmmap", O_RDWR|O_CREAT|O_TRUNC, 0666);
int fd2;
char *base_shared, *base_private, *base_private2;
if (fd == -1) fatal("cannot create test file");
if (write(fd, "test", 4) != 4) fatal("cannot write test file");
base_shared = mmap((caddr_t)0, 10000, PROT_READ,
MAP_SHARED | MAP_FILE| MAP_VARIABLE,
fd, 0L);
if (base_shared == MAP_FAILED) fatal("cannot create shared map");
base_private = mmap((caddr_t)0, 4, PROT_READ,
MAP_PRIVATE | MAP_NORESERVE | MAP_FILE| MAP_VARIABLE,
fd, 0L);
if (base_private == MAP_FAILED) fatal("cannot create private map");
base_private2 = mmap((caddr_t)0, 4, PROT_READ,
MAP_PRIVATE | MAP_NORESERVE | MAP_FILE| MAP_VARIABLE,
fd, 0L);
if (base_private == MAP_FAILED) fatal("cannot create private2 map");
if (strncmp(base_shared, "test", 4) != 0) fatal("shared map does not match");
if (strncmp(base_private, "test", 4) != 0) fatal("private map does not match");
if (write(fd, "test", 4) != 4) fatal("cannot extend test file within page");
fsync(fd);
msync((caddr_t)base_shared, 10000, MS_INVALIDATE);
if (munmap(base_private, 4)) fatal("cannot unmap private map");
base_private = mmap((caddr_t)0, 8, PROT_READ,
MAP_PRIVATE | MAP_NORESERVE | MAP_FILE| MAP_VARIABLE,
fd, 0L);
if (base_private == MAP_FAILED) fatal("cannot create private map second time");
if (strncmp(base_shared+4, "test", 4) != 0) fatal("shared map does not match within page");
if (strncmp(base_private+4, "test", 4) != 0) fatal("private map does not match within page");
fd2 = open("conftestmmap", O_RDWR, 0666);
if (lseek(fd2, 0, 0) == -1) fatal("cannot seek second fd");
if (write(fd2, "xyzy", 4) != 4) fatal("cannot write second fd");
fsync(fd2);
if (munmap(base_private, 8)) fatal("cannot unmap private map");
base_private = mmap((caddr_t)0, 8, PROT_READ,
MAP_PRIVATE | MAP_NORESERVE | MAP_FILE| MAP_VARIABLE,
fd, 0L);
if (base_private == MAP_FAILED) fatal("cannot create private map third time");
if (strncmp(base_private, "xyzy", 4) != 0) fatal("private map does not show change");
{
int i;
for (i = 0; i < 9000; i++) {
if (write(fd, "test", 4) != 4) fatal("cannot extend test file outside page");
}
}
msync((caddr_t)base_shared, 10000, MS_INVALIDATE);
msync((caddr_t)base_private, 10000, MS_INVALIDATE);
if (strncmp(base_shared+9000, "test", 4) != 0) fatal("shared map does not match beyond page");
#if 0
if (strncmp(base_private+9000, "test", 4) != 0) fatal("private map does notmatch beyond page");
#endif
unlink("conftestmmap");
exit(0);
}
---[SNIP]---
--
Andreas Wrede Planix, Inc.
andreas@planix.com Networking, System Administration, Consulting
http://www.planix.com Toronto, Ontario, Canada