This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
(no) GCC pre-compiled headers on Cygwin
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: gcc at gcc dot gnu dot org
- Cc: vinschen at redhat dot com, cgf at redhat dot com
- Date: 22 Jul 2003 04:02:26 -0300
- Subject: (no) GCC pre-compiled headers on Cygwin
- Organization: GCC Team, Red Hat
I've been looking into why GCC pre-compiled headers don't work on
Cygwin. There are several reasons:
- gt_pch_save() mmap()s the file with the expected PCH size before the
file is big enough. Cygwin mmap will fail in this case, because it
truncates the requested mmap size on the file-end boundary, and
then, when mmap_record::map_map checks that a region big enough for
the entire requested size was mapped, it fails. A simple
work-around for this is to ftruncate() to the expected size first:
then mmap() works, and we generate a PCH file with a reasonable
base_address. I think this is a change that would be very
reasonable to make in GCC, given that mmap()ing a region beyond the
end of a file is not portable. Unfortunately, ftruncate isn't
portable either, so we might have to add a poor man's ftruncate() to
libiberty for when it's not available, that saves the current file
position, seeks to EOF, writes NULs to get the file as big as
specified, then restores the saved file position. Of course, this
won't be able to shrink a file, so perhaps calling it ftruncate()
isn't ideal. Alternatively, we might just refrain from calling
ftruncate if it's not available, and just do our best.
- gt_pch_restore() mmap()s the file without MAP_FIXED, passing it the
wanted base address, that gt_pch_save() had obtained from mmap() and
saved in the file, but Cygwin's fhandler_disk_file::mmap() simply
disregards the address when mapping without MAP_FIXED. I don't
understand why it does this. Why doesn't it pass the requested
address to MapViewOfFileEx always? It doesn't seem that it would
fail if the exact address wasn't available but, even if it did,
although mmap is not required to use the given address, except for
MAP_FIXED, mmap should at least favor the given address over other
alternatives, even if this means issuing two calls, one with the
address and one without. Is there a reason for this behavior in
Cygwin?
- Another problem is the way Cygwin copes with granularity of mmaps.
When GCC calls mmap() in gt_pch_save() to choose the base address of
the PCH, it maps the file starting at offset 0. When
gt_pch_restore() calls it, it uses a non-zero offset, that, in spite
of being aligned to a page boundary, is not necessarily aligned to
the allocation granularity. Unfortunately, because of the way
Cygwin (or Windows?) handles granularity, its mmap() cannot *ever*
return the same address as the one gt_pch_save() got for offset 0,
unless the offset turns out to be aligned to the mmap granularity
boundary (64Kb). Even when I forced it to use the same address with
MAP_FIXED, because the offset was mis-aligned by 0x5000, the address
returned by mmap was off by 0x5000. I don't know whether Cygwin's
handling of gran_off and gran_len is based on requirements from
Windows or on its own design decisions, but it seems clear to me
that, at least for a MAP_FIXED request, the address should be *the*
one passed or MAP_FAILED, never the address passed plus
off&(granularity-1) (for nonzero off :-)
Anyway, ideally Cygwin should, if possible, not align file mappings
to the mmap granularity, especially for MAP_FIXED, and it should
definitely fail if it can't satisfy the request to MAP_FIXED to the
given address with a non-granularity- (bug still page-)aligned
offset.
- GCC, on its end, should probably not expect the address returned by
mmap() for offset 0 of the file to be valid for other offsets.
Alternatively, it might attempt to obtain mmap granularity
information from the system, and use that to align the offset,
instead of just the page. This means gt_pch_save() would have to
pre-compute the size of the initial region that is not mmapped, such
that it could call mmap with the same offset that gt_pch_restore is
going to use.
- It would be nice if Cygwin could expose the mmap granularity
information somehow (maybe it already does?), as well as some means
to tell whether a collection of pages is available for mmapping,
somewhat like mincore(), that gt_pch_restore() uses if available in
case mmap doesn't take the base address hint, to check whether the
memory region is available before trying to MAP_FIXED it. We don't
need mincore()s functionality. It's not even clear that such
functionality is available on Windows; I for one know it's not
entirely available on GNU/Linux, but GCC attempts to use it anyhow,
and such use is actually unsafe. However, if we could come up with
another interface that could be used to tell whether a certain page
is mapped or not, we could use it for the same purpose that we
currently use mincore. As long as Cygwin's MAP_FIXED is fixed
and/or we pre-compute the offset and pass it to the save-time mmap
and/or we align the offset to the allocation granularity.
Anyway, we seem to still be a long way from getting PCH on Cygwin :-(
It would be nice if libstdc++ could disable this feature automatically
when it's not present. Unfortunately, it's current test for the
feature's availability is too simple-minded: it only tests whether a
PCH can be created, not whether it can be used. Would a change that
made it fail in the current conditions be acceptable for libstdc++?
--
Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer aoliva@{redhat.com, gcc.gnu.org}
CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist Professional serial bug killer