Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin AT sources DOT redhat DOT com From: "Lothan" To: "Cygwin-L" Subject: RE: Optimizing away "ReadFile" calls when Make calls stat() Date: Wed, 14 Feb 2001 00:45:27 -0800 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2910.0) Importance: Normal X-MimeOLE: Produced By Microsoft MimeOLE V5.00.3018.1300 In-Reply-To: <3A89C304.89BD74A0@etr-usa.com> > From: cygwin-owner AT sources DOT redhat DOT com > [mailto:cygwin-owner AT sources DOT redhat DOT 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 AT curl DOT 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