Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-developers-owner AT sourceware DOT cygnus DOT com Delivered-To: mailing list cygwin-developers AT sourceware DOT cygnus DOT com Message-ID: <779F20BCCE5AD31186A50008C75D9979171728@silldn_mail1.sanwaint.com> From: "Fifer, Eric" To: cygwin-developers AT sourceware DOT cygnus DOT com Subject: mmap() and MAP_FIXED Date: Wed, 10 May 2000 18:40:54 +0100 MIME-Version: 1.0 X-Mailer: Internet Mail Service (5.5.2650.21) Content-Type: text/plain; charset="iso-8859-1" I started to build the apache2.0a3 public alpha and configure fails when checking for a working mmap(). The test (with my workarounds) is attached below. While investigating why the test was failing I stumbled across a few problems: + MapViewOfFileEx() was failing with ERROR_MAPPED_ALIGNMENT (1132) because the base address is supposed to be a multiple of the memory allocation granularity, which is SYSTEM_INFO.dwAllocationGranularity or 64k. But, the test logic aligns on getpagesize() boundaries, which is SYSTEM_INFO.dwPageSize or 4k. + After working around this (pagesize = 65536), MapViewOfFileEx() started failing with ERROR_INVALID_ADDRESS (487), which means that you can't map over an address already allocated by VirtualAlloc(). By making sure the address is past anything already allocated (data2 += 10000 * pagesize) the test succeeds. I also tried releasing the underlying memory with VirtualFree(), but this only works if you decommit/release the same range of pages originally allocated with VirtualAlloc(), and any fix here required some significant changes to heap.cc. I wasn't able to find any prior discussion of these issues. Are these known problems? This isn't a big deal, because in the end Apache doesn't use MAP_FIXED (only configure does). Thanks. Eric -- #include #include #include char *malloc(); int main() { char *data, *data2, *data3; int i, pagesize; int fd; pagesize = getpagesize(); pagesize = 65536; /* WORKAROUND 1 */ /* * First, make a file with some known garbage in it. */ data = malloc(pagesize); if (!data) exit(1); for (i = 0; i < pagesize; ++i) *(data + i) = rand(); umask(0); fd = creat("conftestmmap", 0600); if (fd < 0) exit(1); if (write(fd, data, pagesize) != pagesize) exit(1); close(fd); /* * Next, try to mmap the file at a fixed address which * already has something else allocated at it. If we can, * also make sure that we see the same garbage. */ fd = open("conftestmmap", O_RDWR); if (fd < 0) exit(1); data2 = malloc(2 * pagesize); data2 += 10000 * pagesize; /* WORKAROUND 2 */ if (!data2) exit(1); data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1); if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0L)) exit(1); for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data2 + i)) exit(1); /* * Finally, make sure that changes to the mapped area * do not percolate back to the file as seen by read(). * (This is a bug on some variants of i386 svr4.0.) */ for (i = 0; i < pagesize; ++i) *(data2 + i) = *(data2 + i) + 1; data3 = malloc(pagesize); if (!data3) exit(1); if (read(fd, data3, pagesize) != pagesize) exit(1); for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data3 + i)) exit(1); close(fd); unlink("conftestmmap"); exit(0); }