Mail Archives: cygwin-developers/2000/05/10/12:39:04
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 <sys/types.h>
#include <fcntl.h>
#include <sys/mman.h>
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);
}
- Raw text -