Don't stat(/etc/localtime) between read() and write() copying files
ClosedPublic

Authored by jtamate on Jan 19 2018, 4:34 PM.

Details

Summary

CCBUG: 384561

Unfortunately, QDateTime::currentDateTime() checks /etc/localtime
each time it is called.
Chaning to QElapsedTime, no check of /etc/localtime.
Reproducing bug 384561, the strace of file.so was something like:
read(), stat(/etc/localtime), stat(/etc/localtime),
stat(/etc/localtime), stat(/etc/localtime), stat(/etc/localtime),
write(), read() ......
Now it is: read(), write()
It also reduces the cpu in io/wait around 10% in a debug build.

Test Plan

kio tests work as before
desktop: works in dolphin

Diff Detail

Repository
R241 KIO
Branch
timer (branched from master)
Lint
No Linters Available
Unit
No Unit Test Coverage
jtamate created this revision.Jan 19 2018, 4:34 PM
Restricted Application added a project: Frameworks. · View Herald TranscriptJan 19 2018, 4:34 PM
jtamate requested review of this revision.Jan 19 2018, 4:34 PM
fvogt requested changes to this revision.Jan 22 2018, 6:27 PM
fvogt added a subscriber: fvogt.
fvogt added inline comments.
src/core/slavebase.cpp
279 ↗(On Diff #25644)

In the old code the timeout was canceled here, but now it gets started again instead.

1052 ↗(On Diff #25644)

If I understand this correctly, this will change behaviour.
It'll call the timeout function on the next dispatchLoop call.

This revision now requires changes to proceed.Jan 22 2018, 6:27 PM
jtamate added inline comments.Jan 22 2018, 7:00 PM
src/core/slavebase.cpp
279 ↗(On Diff #25644)

Reading the documentation http://doc.qt.io/qt-5/qelapsedtimer.html
I'm not able to say if start() will restart a timer or continue. My guess is that it also restarts.
And also because calling restart() on a QElapsedTimer that is invalid results in undefined behavior.

1052 ↗(On Diff #25644)
beforenowwhere
next = now + timeoutmsecs = timeout, (re)start elapsedsetTimeoutSpecialCommand
if next < now thenif has elapsed timeout thendispatchLoop

I think both are equivalent.

fvogt added a comment.Jan 22 2018, 7:42 PM

Just a quick idea, it might be wrong: If you use a QTimer instead of QElapsedTimer, you can get rid of nextTimeoutMsecs. This would also simplify the logic a bit.

src/core/slavebase.cpp
279 ↗(On Diff #25644)

This does not matter - previously this line guaranteed that this does not fire again until nextTimeout is set again. Now it will fire on the next dispatchLoop() call.

You probably want to call d->nextTimeout.invalidate() here.

1052 ↗(On Diff #25644)

You probably want to call invalidate here as well and then not start() it in this case.

In D9983#194505, @fvogt wrote:

Just a quick idea, it might be wrong: If you use a QTimer instead of QElapsedTimer, you can get rid of nextTimeoutMsecs. This would also simplify the logic a bit.

QTimer and I have a strange relationship and I try to avoid it. But feel free to implement it that way.

src/core/slavebase.cpp
279 ↗(On Diff #25644)

You're right. I missed that QDateTime() generates an invalid datetime.

1052 ↗(On Diff #25644)

If you are talking only in the last case // canceled. You are right again (the same mistake).

jtamate updated this revision to Diff 25783.Jan 22 2018, 8:37 PM
  • Don't stat(/etc/localtime) between read() and write() copying files

    Fix logic of cancelations
fvogt resigned from this revision.Jan 22 2018, 9:02 PM

This should work now - I won't give the revision a total accept though as I didn't test it myself.

dfaure requested changes to this revision.Jan 24 2018, 8:35 AM
dfaure added inline comments.
src/core/slavebase.cpp
1052

Typo: In -> Im (i.e. it was correct in the orig code)

1054

Where does this "1" value come from, and it is useful at all?

1055

So when we go to that "else" branch, we'll have called start() and immediately after, invalidate(). To avoid doing this, how about calling start() in the first two if()s?
(small optimization)

This revision now requires changes to proceed.Jan 24 2018, 8:35 AM
jtamate updated this revision to Diff 25867.Jan 24 2018, 11:00 AM
jtamate marked 3 inline comments as done.
jtamate added inline comments.
src/core/slavebase.cpp
1054

It was 1 as could have been 0.
It is not needed anymore.

1055

I was trying to save some code, but you're right. Here speed matters more than size.

jtamate marked 2 inline comments as done.Feb 6 2018, 3:09 PM

So, good to go?

dfaure accepted this revision.Feb 7 2018, 8:32 AM
This revision is now accepted and ready to land.Feb 7 2018, 8:32 AM
This revision was automatically updated to reflect the committed changes.