Closed Bug 122523 Opened 23 years ago Closed 23 years ago

Avoid stat call when opening file.

Categories

(Core :: Networking, defect)

x86
Windows 2000
defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla0.9.9

People

(Reporter: dougt, Assigned: dougt)

Details

(Whiteboard: fix in hand)

Attachments

(2 files, 5 obsolete files)

We should try to avoid the stat() call when we are opening a file. Instead gain
stat info via the file descriptor.

If we change this pattern:

    PR_GetFileInfo64(INPUT_FILE, &info);
    fd = PR_Open(INPUT_FILE, PR_RDWR | PR_CREATE_FILE, 00666);

to this:

    fd = PR_Open(INPUT_FILE, PR_RDWR | PR_CREATE_FILE, 00666);
    PR_GetOpenFileInfo64(fd, &info);

we should see a improvement of 50%.  How this plays out in the mozilla file
transport, I am not sure yet.
Attached patch changes v.1 (obsolete) — Splinter Review
Attached file nspr stat test. (obsolete) —
Attachment #67030 - Attachment is obsolete: true
Attached patch and now for something that works (obsolete) — Splinter Review
Attachment #67027 - Attachment is obsolete: true
Attached patch how about this time... v.3 (obsolete) — Splinter Review
Attachment #67044 - Attachment is obsolete: true
Here some test results on a 
win98, 200MHz 64MB machine

startup (warm)
------------------
original:  8850, 8790, 8490, 8490, 8920, 8810 --> avg 8725 ms
w/ patch:  8400, 8980, 8510, 8000, 8120, 8670 --> avg 8446 ms
                                             -----------------
                                                 diff  279 ms   ( -3.19%)


page-load
------------------
original:  2646, 2645, 2647 --> avg 2646 ms
w/ patch:  2641, 2641, 2624 --> avg 2635 ms
                            ------------------
                               diff   11 ms   ( -0.4 %)
                              


memory after page-load
-------------------------
original:  Data KB  20,124, 20,424
           Code KB   9,596   9,596 

w/ patch:  Data KB  18,252  18,444
           Code KB   9,580   9,600

(appear to have shaved off some Data or VM size)

   

                            

Cathleen, thanks for this data. :-)

Does anyone understand why this patch cut ~2mb of data?  Please, do not tell me
that PR_GetFileInfo64 is that expensive! 
It is baffling this patch can reduce 2MB of data. Maybe app didn't need to
sbrk() to get that extra 2MB because of the change in malloc pattern and things
just aligned !!!
Target Milestone: --- → mozilla0.9.9
looking at unix and mac, I do not think that a similar optimization is possible
unless we invest alot more time - eg. switching over to nsprs' FileInfo(64) stat
structure. 
 
is there another way to avoid a stat when opening a file? 
dp, can you review these changes?
Comment on attachment 67046 [details] [diff] [review]
how about this time... v.3

 if (isDir) {
+	 PR_Close(mFD);


Are we sure mFD will be set here ?

r=dp otherwise
Attachment #67046 - Flags: review+
It is protected above.  If mFD is null Open() will be called.  If open succeeds,
mFD will vaild.  Just to be a bit paranoid, i will add a assertion.
dougt: nsLocalFileUnix could use fstat in place of stat when it already has a
file descriptor.
right, but files usually get opened with openNSPRFileDesc().  calling fstat() on
a nspr file descriptor probably won't work.
what about this:

  struct stat buf;
  fstat(PR_FileDesc2NativeHandle(nsprFD), &buf);

isn't this valid?
now that is a routine I have not seen before!
it's in pprio.h and fwiw we already use it in nsFileStreams.cpp to support file
truncation (nsISeekableStream::SetEOF).
Oh... that is why i didn't see it.  It is both private and obsolete. :-/
Comment on attachment 67046 [details] [diff] [review]
how about this time... v.3

>+    nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(mFile, &rv);
>+    if (NS_FAILED(rv)) return rv;
>+    if (mIOFlags == -1)
>+        mIOFlags = PR_RDONLY;
>+    if (mPerm == -1)
>+        mPerm = 0;

What do these magic -1's mean/do? Is there a descriptive #define or const for
it?

>+    if (!mFD) {
>+        // NS_ASSERTION(mFD, "Your suppose to call Open()");

Take out the comment, or at least fix the spelling ("You're supposed...")

> nsFileInputStream::Init(nsIFile* file, PRInt32 ioFlags, PRInt32 perm, PRBool deleteOnClose)
>-{
>-    NS_ASSERTION(mFD == nsnull, "already inited");
>-    if (mFD != nsnull)
>-        return NS_ERROR_FAILURE;
>-    nsresult rv;
>+{   
>+    nsresult rv = NS_OK;
>     nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(file, &rv);
>     if (NS_FAILED(rv)) return rv;
>     if (ioFlags == -1)
>@@ -469,10 +489,22 @@
>     if (perm == -1)
>         perm = 0;
> 
>-    mLineBuffer = nsnull;
>-    
>-    rv = localFile->OpenNSPRFileDesc(ioFlags, perm, &mFD);
>+    PRFileDesc* fd;
>+    rv = localFile->OpenNSPRFileDesc(ioFlags, perm, &fd);
>     if (NS_FAILED(rv)) return rv;

Where did this fd come from? I assume you compiled this so it must be
there somewhere, but it's hard to tell with so little context.

sr=dveditz
Attachment #67046 - Flags: superreview+
What do these magic -1's mean/do? Is there a descriptive #define or const for
it?

no defines or const.  They are well known values in the stream code.


>+    if (!mFD) {
>+        // NS_ASSERTION(mFD, "Your suppose to call Open()");

Take out the comment, or at least fix the spelling ("You're supposed...")

I did.  thanks.

>+    PRFileDesc* fd;  <--------------------------------------
>+    rv = localFile->OpenNSPRFileDesc(ioFlags, perm, &fd);
> if (NS_FAILED(rv)) return rv;

Where did this fd come from? I assume you compiled this so it must be
there somewhere, but it's hard to tell with so little context.
 
cc'ing wtc... can you comment on comment #15.  thx!
Darin,

Why don't you replace the fstat() call by a PR_GetOpenFileInfo64()
or PR_GetOpenFileInfo() call?  PR_FileDesc2NativeHandle() is a
semi-private function that should only be used when there is no
NSPR alternative.

Checking in nsFileStreams.cpp;
/cvsroot/mozilla/netwerk/base/src/nsFileStreams.cpp,v  <--  nsFileStreams.cpp
new revision: 1.32; previous revision: 1.31
done
Checking in nsFileStreams.h;
/cvsroot/mozilla/netwerk/base/src/nsFileStreams.h,v  <--  nsFileStreams.h
new revision: 1.16; previous revision: 1.15

Checking in nsLocalFileWin.cpp;
/cvsroot/mozilla/xpcom/io/nsLocalFileWin.cpp,v  <--  nsLocalFileWin.cpp
new revision: 1.78; previous revision: 1.77
done

We can file a seperate bug on converting the Unix version of nsLocalFile over to
using the nspr file info structure if you like.  I am not sure if the current
owners of this agree with doing this.  brendan, shaver, ?
May I suggest that open+fstat is a big win on unix because it avoids a 
potential race condition. It's also slightly faster on Linux.
Keywords: nsbeta1+
I checked in the windows version nsLocalFile changes without any problems, but
the nsFileStream stuff just doesn't work on linux clobber.  Even after I fixed
the mLineBuffer crash, the build stays yellow.

I don;t think that this matters all that much anymore since the cache is going
to be moving to a blocked file format.  I am futuring this until I can find time
to look at the crash.

Cathleen, DP, If you want to figure out why |brad| went yellow, please reassign. :-)
Keywords: helpwanted
Target Milestone: mozilla0.9.9 → Future
I moved this to future out of frustration... resetting milestone...  sorry about
that. 
Target Milestone: Future → ---
Attached patch fixes up mLineBuffer (obsolete) — Splinter Review
Attachment #67046 - Attachment is obsolete: true
chris and I spun seperate clobber builds with the last patch and both were
successful.  I have sent mail to the build owner of the "Brad" tinerbox so that
we can work out a way where this orangeness can be tracked down.
Fixes a infinite loop cause by the mimeservice wanting to open a file.
Attachment #69606 - Attachment is obsolete: true
Comment on attachment 70370 [details] [diff] [review]
fixes infinite loop problem.

r=bbaetz
Attachment #70370 - Flags: review+
Comment on attachment 70370 [details] [diff] [review]
fixes infinite loop problem.

sr=darin

some nits:

1-

if(contentLength)

should be

if (contentLength)


2- 

nsCRT::strdup("literal-string")

can be replaced with:

strdup("literal-string")

there's no fear of invoking the wrong allocator here.
Attachment #70370 - Flags: review+ → superreview+
Target Milestone: --- → mozilla0.9.9
Keywords: helpwanted
Whiteboard: fix in hand
> 2- 
> nsCRT::strdup("literal-string")
> can be replaced with:
> strdup("literal-string")
> there's no fear of invoking the wrong allocator here.

But there should be fear of invoking the wrath of the Mac!
yup... the mac will go red, but will return.  

Fixes checked in to 0.99
Status: NEW → RESOLVED
Closed: 23 years ago
Resolution: --- → FIXED
dbaron: LXR tells me that strdup is used all over the place.  am i missing
something?
in any case, paranoia got me and I changed my strdup's to nsCRT::strdup's to
avoid bustage.  
Maybe it requires a different header?
Doug, I think you may have accidentally got part of patch from bug 122892
checked in when you checked in this one, that was previously backed out. This
caused a memory leak. You can see bug 124497 for more details. Just trying to
get this all tied together.
dougt: are there any steps I can use to reproduce/verify this problem?

This is on my verification list.
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: