This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin 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]

Re: ksh on cygwin


On Fri, Jan 11, 2002 at 09:32:57PM +1100, Robert Collins wrote:
> ----- Original Message -----
> From: "Corinna Vinschen" <cygwin@cygwin.com>
> 
> > mmap (MapViewOfFile resp.) alwaus map whole pages.  A page is 4096
> > bytes long.
> >
> > If a file is, say, 8190 bytes, then we have a two page map, size 8192.
> > So we have two trailing 0 bytes.  If getpagesize() returns 4096, gcc
> can
> > count that correctly, if getpagesize returns 65536, gcc assumes 57346
> > trailing bytes.  No problem, gcc only accesses exactly one trailing 0
> byte.
> >
> > If the file is 8192 bytes long, mmap maps exactly 8192 bytes, no
> > trailing bytes left.  If getpagesize() returns 4096, gcc knows that,
> > if getpagesize returns 65536, gcc assumes 57344 trailing bytes.
> > Now it is a problem, since the one trailing 0 byte doesn't exist.
> > Segmentation fault.
> 
> Ok. Lets see if I understand:
> 
> Let m be the size reported by getpagesize.
> Let f be the size of a file gcc is mmaping.
> 
> 1) Gcc can't handle a remainder of m divided by f that is greater than
> <some number between  2 and 57346>.
> 
> 2) If the remainfer of m divided by f is 0, gcc behaves correctly.
> 
> 3) If f > m, then gcc assumes that f is m bytes long?
> 
> Sounds to me like gcc is badly broken.
> i.e. in your prior example:
> where m = 4096
> if the file is 2048 bytes long, mmap maps exactly 2048 bytes.

No, it maps 4096 bytes since memory maps always use chunks of
the pagesize which is 4096 on Win32.

if m is
> 4096, gcc assumes there is  2048 trailing bytes. Now it is a problem,
> since the one trailing 0 byte doesn't exist. Segmentation fault.
> 
> IOW, I don't see how the 4K vs 64K thing affects this scenario, it seems
> to be driven purely by the fact the m != 1.

Sorry but you didn't understand or I don't understand your
above reasoning which is likely.

GCC isn't broken (from the gcc's engineers point of view) but it's
using a property of mmap: mmap always maps whole pages and the
trailing unused bytes in a mmap'd page are always zeroed out.

This fact is used for some sort of speed up when reading header
files.  IMO that's ugly but...
Anyway, gcc reads a C header file just as a string with trailing 0.

For that reason gcc has to know the pagesize of the system, returned
by getpagesize().

If the file size is not exactly a multiple of the pagesize, you
always have a trailing zero so gcc can use the above method.  If
a file has no trailing 0 byte (which would happen very seldom)
gcc would have to fallback to another method (I do know nothing
about).

Now, the pagesize on Windows is 4K.  If the file size is coincidentally
4096 or 8192 or any other multiple of 4K, gcc knows that it has to
fallback to it's "slow" method since getpagesize() has returned the
correct value.  If we change getpagesize() to return the granularity
(64K) instead of the pagesize, gcc would wrongly assume that the
file doesn't exactly match the pagesize so it would assume that
it can use the "fast" method and would expect a trailing 0 byte.

Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Developer                                mailto:cygwin@cygwin.com
Red Hat, Inc.

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


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