Closed
Bug 123273
Opened 23 years ago
Closed 22 years ago
setTimeout(something, 0) causes 100% CPU constant
Categories
(Core :: DOM: Core & HTML, defect, P2)
Core
DOM: Core & HTML
Tracking
()
VERIFIED
FIXED
mozilla1.1beta
People
(Reporter: jmd, Assigned: jst)
References
()
Details
(Whiteboard: [HAVE FIX])
Attachments
(2 files)
179 bytes,
text/html
|
Details | |
1013 bytes,
patch
|
bzbarsky
:
review+
jst
:
superreview+
|
Details | Diff | Splinter Review |
I'm guessing javascript... with that menu that follows the scroll.
100% CPU use remains even when the browser tab or window doesn't have focus.
Comment 1•23 years ago
|
||
this page contains the following JavaScript:
function makeStatic() {
if (ie4) {...}
else if (ns6) {...}
else if (ns4) {...}
setTimeout("makeStatic()",0);
}
the function is intended to reposition the menu when you scroll, but it
basically runs continuously.
Comment 2•23 years ago
|
||
Confirming with Mozilla trunk builds 20020125xx WinNT
OS: Linux ---> All. Here is a larger excerpt from the site:
/*
Static menu script II (By maXimus, maximus@nsimail.com,
http://maximus.ravecore.com/)
Modified slightly/ permission granted to Dynamic Drive
to feature script in archive For full source, usage terms,
and 100's more DHTML scripts, visit http://dynamicdrive.com
*/
//configure below variable for menu width, position on page
var menuwidth=115
var offsetleft=645
var offsettop=40
var ns4=document.layers?1:0
var ie4=document.all?1:0
var ns6=document.getElementById&&!document.all?1:0
function makeStatic() {
if (ie4) {
object1.style.pixelTop=document.body.scrollTop+offsettop
}else if (ns6) {
document.getElementById("object1").style.top=window.pageYOffset+offsettop
}else if (ns4) {
eval(document.object1.top=eval(window.pageYOffset+offsettop));
}
setTimeout("makeStatic()",0);
}
if (ie4||ns6) {
document.write('<span ALIGN="CENTER" ID="object1" STYLE="Position:absolute;
Top:20; Left:'+offsetleft+';
Z-Index:5;cursor:hand;background-color:black;"><TABLE BORDER="1"
width="'+menuwidth+'" CELLPADDING="0" CELLSPACING="0" BORDERCOLOR="black"
bgcolor="white">')
}else if (ns4){
document.write('<LAYER top="20" name="object1" left="'+offsetleft+'"
BGCOLOR=black><TABLE BORDER="0" CELLPADDING="0" CELLSPACING="1"><TR><TD>
<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" width="'+menuwidth+'">')
}
Status: UNCONFIRMED → NEW
Ever confirmed: true
OS: Linux → All
Hardware: PC → All
Comment 3•23 years ago
|
||
And farther down, here is what starts the cycle:
window.onload=menu3;
function menu3()
{
if (ns6||ie4||ns4)
makeStatic()
}
Comment 4•23 years ago
|
||
I don't know why this use of setTimeout('something', 0) pins the CPU
in Mozilla, but not NN4.x or IE6. Reassigning to DOM Level 0 to find out.
This simple script, which I will attach below, is enough to do it:
<HTML><HEAD><TITLE>Bug 123273</TITLE><SCRIPT>
window.onload= makeStatic;
function makeStatic()
{
setTimeout("makeStatic()",0);
}
</SCRIPT></HEAD><BODY></BODY></HMTL>
Assignee: rogerl → jst
Component: JavaScript Engine → DOM Level 0
QA Contact: pschwartau → desale
Comment 5•23 years ago
|
||
Comment 6•23 years ago
|
||
Perhaps NS4 and IE have a minimum timeout. If Mozilla actually attempts to do a
0 timeout, it *should* use 100% of the CPU. It's really just an infinite loop.
Comment 7•23 years ago
|
||
Netscape4 uses 100% on your testcase. In fact, NS4 uses 100% for the URL also
for me.
I tested how often it called. On one machine, it called ~1000 times per second,
but on another it did ~5600 calls per second. Netscape did ~1300 calls/sec on
the first machine, and ~6000 calls/sec on the second.
IE does not exhibit this "bug" because (on one machine at least) it only does
~18 calls/sec!
Comment 8•23 years ago
|
||
Severity = HIGH [Using 100% cpu is as good as crash, Severe functional failure,
No Cosmetic failure]
Visibility = MEDIUM [Real world website usage, Gets one point of
compatibility with other browsers since it works better on IE. gets one
more point on compliance with adopted techonology, that is JS]
Priority = Visibility * Severity
Priority = p2
adding word "qawanted" because I'm setting this priority on available data & if
someone feels otherwise then please investigate this more & feel free to change
this priority.
Keywords: qawanted
Priority: -- → P2
Comment 9•23 years ago
|
||
It seems Mozilla should have a reasonable minimum timeout value, or this should
be WONTFIX (or moved to Evang, setting 0 timeout is a bit silly). FWIW, my vote
would be for WONTFIX/Evang.
Comment 10•23 years ago
|
||
I've found another URL where the CPU gets pegged in Mozilla. Figuring it's
probably not cool to file another bug, I'll just add comments here. The bug is:
http://www.attws.com/mobileinternet/
Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.0rc1) Gecko/20020415
Comment 11•23 years ago
|
||
Dameon: the site works fine for me, but if it is banging the CPU for you, it's
probably a different (possibly new) bug.
Comment 12•23 years ago
|
||
Okay, will file a different bug
Comment 13•23 years ago
|
||
> Perhaps NS4 and IE have a minimum timeout. If Mozilla actually
> attempts to do a 0 timeout, it *should* use 100% of the CPU.
> It's really just an infinite loop.
Based on Andrew's comment, as I understand things, there are
two possible ways to resolve this bug:
1) Defend against setTimeout(something, 0) by establishing
an effective minimum timeout value. A developer could
write setTimeout(something, 0) without causing an error,
but effectively it wouldn't have that meaning.
2) Otherwise, this bug is a just a duplicate of bug 13350,
"DOM needs to police JS infinite loops, schedule garbage collection"
Does that sound right?
Comment 14•23 years ago
|
||
Resummarizing; cc'ing Andrew -
Summary: Page uses 100% CPU constant... no animated images/plugins → setTimeout(something, 0) causes 100% CPU constant
Comment 15•23 years ago
|
||
yup. Although, I don't know if the logic in bug 13350 would catch this because
the function is called repeatedly rather than one function never exiting.
Comment 16•23 years ago
|
||
*** Bug 137667 has been marked as a duplicate of this bug. ***
Comment 17•23 years ago
|
||
The simplified test case pins my CPU on Win2k, Moz 1.0RC1.
(Heh, this ended up being the right bug after all... :-)
Comment 18•23 years ago
|
||
*** Bug 134149 has been marked as a duplicate of this bug. ***
Comment 19•23 years ago
|
||
While looking at bug 134149 (a dupe of this bug), I was trying to figure out why
IE doesn't eat 100% CPU like Mozilla. I wrote some JavaScript code with a
function that calls itself 200 times using setTimeout() with timeout = 0. It
repeats this for all values of timeout up to 50 and displays the wall clock time
it took for each group of 200 calls. I then imported the data into Excel and
created a graph showing runtime vs. delay/timeout value for IE, Mozilla, and
Opera. The tests were run under NT4WS+SP6a on a dual PII/333 w/ 320 megs of
RAM, and even though they may be statistically worthless, I figured they might
provide some insight.
http://www.cs.wcu.edu/~rwg/moz/123273/ has the code and graph. The .pdf
contains the graph, and the .txt and .html files contain the HTML and JavaScript
I used to generate the data -- the only difference is the Content-Type returned
by the server (text/plain vs. text/html). [I'd upload these as attachments to
the bug, but I'm not sure they'd really belong there. I'll make them
attachments if requested.]
At first glance, I thought IE must limit timeouts < 15 ms to 15 ms, but that
doesn't explain the other horizontal segments on the graph. Opera shows the
same behavior except at timeout = 0. (Bug?) I'm not sure if IE and Opera round
the timeout value to the next highest multiple of 16 or if the weird graph is a
result of some interaction between the timeout value and the OS's timeslice
length. Maybe Opera and IE use a timing mechanism that causes them to forfeit
the rest of their timeslice. I just don't know. :)
At any rate, my vote would be to squash the bug by imposing a minimum timeout
for calls to setTimeout (unless there's JavaScript code used by Mozilla itself
that this would break, of course). If nobody notices, it doesn't break
anything, and it makes the UI more responsive, that seems like a win-win to me.
Assignee | ||
Comment 20•23 years ago
|
||
Comment 21•23 years ago
|
||
This is basically the same conclusion I came to in bug 111982... we spend so
much time trying to service SetTimeout() callbacks, that everything else grinds
to a halt. I don't know if other browsers arbitrarily limit this frequency or
what...
Our ability to service the timer callback tends to be determined by what is
going on in the page... It would be nice if we could determine, on a per page
basis, our ability to service the timer callback and programatically adjust the
floor for callback servicing.
Comment 22•22 years ago
|
||
*** Bug 146983 has been marked as a duplicate of this bug. ***
Comment 23•22 years ago
|
||
*** Bug 152531 has been marked as a duplicate of this bug. ***
Comment 24•22 years ago
|
||
my two cents:
IE and Opera are probably using the Windows API SetTimer() call, which has an
average resolution of ~16ms (depending on how often the calling thread is being
scheduled, what other messages are being posted to the message queue, and
whether the message is to a foreground window. 10ms is minimum and 22ms is max).
IE/Opera behaviour could be emulated by making the timeout evenly divisible by
16. Something like:
#define TIMER_RES 0x10 //16ms
if (interval >= ((~TIMER_RES)+1)) /* prolly should not do timer */
timeout->interval = ((~TIMER_RES)+1); /* on overflow or < 0 */
else if (interval < 1) /* catch negative values too */
timeout->interval = TIMER_RES;
else
timeout->interval = (PRInt32) interval;
if (timeout->interval % TIMER_RES)
timeout->interval += (TIMER_RES - (timeout->interval % TIMER_RES));
Assignee | ||
Comment 25•22 years ago
|
||
Do we really care about emulating timer resolution here? I agree that we should
put a minimum value on JS timeouts (16ms?) but other than that I don't really
see the need for emulating the not-precicely-predictable-anyway resolution of
windows timers when timers are never that precise anyways. I.e. IMO the attached
patch should be all we need.
bz, wanna review the attached patch? We could change the min value to 16ms tho...
Status: NEW → ASSIGNED
Whiteboard: [HAVE FIX]
Target Milestone: --- → mozilla1.1beta
Comment 26•22 years ago
|
||
Comment on attachment 84079 [details] [diff] [review]
Set 10ms as the min limit for JS timeouts
r=bzbarsky
Attachment #84079 -
Flags: review+
Assignee | ||
Comment 27•22 years ago
|
||
Comment on attachment 84079 [details] [diff] [review]
Set 10ms as the min limit for JS timeouts
Rick says sr=rpotts
Attachment #84079 -
Flags: superreview+
Assignee | ||
Comment 28•22 years ago
|
||
Fix checked in.
Status: ASSIGNED → RESOLVED
Closed: 22 years ago
Resolution: --- → FIXED
Reporter | ||
Comment 29•22 years ago
|
||
verified w/ linux 2002062004. Negligible CPU use. (course, when scrolling that
page, JS sucks 100%, but that's expected, since JS sucks for real-time movement).
Status: RESOLVED → VERIFIED
Keywords: qawanted
You need to log in
before you can comment on or make changes to this bug.
Description
•