This is the mail archive of the cygwin@sources.redhat.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]

RE: Optimizing away "ReadFile" calls when Make calls stat()


> From: cygwin-owner@sources.redhat.com
> [mailto:cygwin-owner@sources.redhat.com]On Behalf Of Warren Young
> Sent: Tuesday, February 13, 2001 3:28 PM
> To: Cygwin-L
> Subject: Re: Optimizing away "ReadFile" calls when Make calls stat()
>
>
> jik-cygwin@curl.com wrote:
> >
> > As I've noted separately, reading tens of thousands of files even once
> > incurs a significant performance penalty.  The change I've proposed
> > can eliminate reading them at all.
>
> Even stat() under Linux does at least one disk read.  You can't
> completely optimize away disk I/O for stat().
>
> The main culprit is that this is one of many places where Unix doesn't
> map onto Win32 well at all.  The VC++ RTL doesn't use ReadFile() to
> implement _stat() at all.  When it checks for things like stat.st_mode
> == S_IEXEC, it simply checks the filename extension for .exe, .com or
> .bat.  Cygwin can't do that -- it must look at the file's magic bytes to
> see if it's an executable, or a #! style script.
>
> stat() on Unixen doesn't do either of these things; all the info stat()
> reports is in the inode.  The info in a prototypical Unix inode is
> scattered in many different places in Win32, which makes the emulator
> for a call like stat() slow.
>
> Maybe a better optimization strategy would be to patch GNU Make.
> Wherever it does a stat() to find the modification time, do something
> like this:
>
>         struct stat st;
> #ifdef CYGWIN
>         WIN32_FIND_DATA findinfo;
>         HANDLE h = FindFirstFile(filename, &findinfo);
>         st.st_mtime = findinfo.ftLastWriteTime;
>         FindClose(h);
> #else
>         stat(filename, &st);
> #endif

Your method is simpler, but I think it's actually faster to call GetFileTime
on an open file handle rather than go through the FindFirstFile API.

	struct stat st;
#ifdef CYGWIN
	HANDLE hFile;
	FILETIME CreationTime;
	FILETIME LastAccessTime;
	FILETIME LastWriteTime;
	hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ |
FILE_SHARE_WRITE, null, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, null);
	GetFileTime(hFile, &CreationTime, &LastAccessTime, &LastWriteTime);
	st.st_mtime = LastWriteTime
	CloseHandle(hFile);
#else
	stat(filename, &st);
#endif

In the case of make, it may be even simpler roll an internal stat() function
that uses GetFileInformationByHandle(), since that seems to include
everything make needs (with mild translation of Windows attributes to *nix
attributes). Of course, one must remember that Windows API functions are not
aware of symbolic links. Caveat emptor.

> (ftLastWriteTime will probably need translation into a time_t, but
> that's a small matter.)


--
Want to unsubscribe from this list?
Check out: http://cygwin.com/ml/#unsubscribe-simple


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