This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

(no) GCC pre-compiled headers on Cygwin


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]