Last Comment Bug 123273 - setTimeout(something, 0) causes 100% CPU constant
: setTimeout(something, 0) causes 100% CPU constant
Status: VERIFIED FIXED
[HAVE FIX]
:
Product: Core
Classification: Components
Component: DOM: Core & HTML (show other bugs)
: Trunk
: All All
: P2 normal (vote)
: mozilla1.1beta
Assigned To: Johnny Stenback (:jst, jst@mozilla.com)
: Prashant Desale
Mentors:
https://www.bj21satellite.com/order1....
: 134149 137667 146983 148638 152531 (view as bug list)
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2002-02-03 17:32 PST by Jeremy M. Dolan
Modified: 2013-08-09 04:54 PDT (History)
20 users (show)
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments
Reduced testcase: pins CPU in Mozilla, but not NN4.x or IE6 (179 bytes, text/html)
2002-02-04 09:12 PST, Phil Schwartau
no flags Details
Set 10ms as the min limit for JS timeouts (1013 bytes, patch)
2002-05-17 10:19 PDT, Johnny Stenback (:jst, jst@mozilla.com)
bzbarsky: review+
jst: superreview+
Details | Diff | Splinter Review

Description Jeremy M. Dolan 2002-02-03 17:32:09 PST
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 Andrew Schultz 2002-02-03 18:04:12 PST
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 Phil Schwartau 2002-02-04 08:43:15 PST
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+'">')
}
Comment 3 Phil Schwartau 2002-02-04 09:04:38 PST
And farther down, here is what starts the cycle:

window.onload=menu3;

function menu3()
{
  if (ns6||ie4||ns4)
  makeStatic()
}
Comment 4 Phil Schwartau 2002-02-04 09:10:31 PST
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>
Comment 5 Phil Schwartau 2002-02-04 09:12:48 PST
Created attachment 67736 [details]
Reduced testcase: pins CPU in Mozilla, but not NN4.x or IE6
Comment 6 Andrew Schultz 2002-02-04 10:27:36 PST
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 Andrew Schultz 2002-02-10 09:36:08 PST
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 Prashant Desale 2002-03-15 14:58:46 PST
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.
Comment 9 Andrew Schultz 2002-04-13 20:17:06 PDT
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 Dameon D. Welch-Abernathy 2002-04-15 18:57:23 PDT
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 Andrew Schultz 2002-04-15 19:08:24 PDT
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 Dameon D. Welch-Abernathy 2002-04-15 19:30:25 PDT
Okay, will file a different bug
Comment 13 Phil Schwartau 2002-04-16 10:05:26 PDT
> 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 Phil Schwartau 2002-04-16 10:08:33 PDT
Resummarizing; cc'ing Andrew -
Comment 15 Andrew Schultz 2002-04-16 11:25:33 PDT
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 Adam Lock 2002-04-23 12:40:11 PDT
*** Bug 137667 has been marked as a duplicate of this bug. ***
Comment 17 Dameon D. Welch-Abernathy 2002-04-23 15:01:57 PDT
The simplified test case pins my CPU on Win2k, Moz 1.0RC1.

(Heh, this ended up being the right bug after all... :-)
Comment 18 Boris Zbarsky [:bz] (still a bit busy) 2002-05-16 20:29:25 PDT
*** Bug 134149 has been marked as a duplicate of this bug. ***
Comment 19 Richard Godbee 2002-05-16 22:54:04 PDT
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.
Comment 20 Johnny Stenback (:jst, jst@mozilla.com) 2002-05-17 10:19:39 PDT
Created attachment 84079 [details] [diff] [review]
Set 10ms as the min limit for JS timeouts
Comment 21 Brian Nesse (gone) 2002-05-17 10:24:37 PDT
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 Boris Zbarsky [:bz] (still a bit busy) 2002-05-25 17:10:39 PDT
*** Bug 146983 has been marked as a duplicate of this bug. ***
Comment 23 Boris Zbarsky [:bz] (still a bit busy) 2002-06-18 01:49:40 PDT
*** Bug 152531 has been marked as a duplicate of this bug. ***
Comment 24 Cyrus Patel 2002-06-18 08:05:33 PDT
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));


Comment 25 Johnny Stenback (:jst, jst@mozilla.com) 2002-06-18 08:49:41 PDT
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...
Comment 26 Boris Zbarsky [:bz] (still a bit busy) 2002-06-18 17:33:20 PDT
Comment on attachment 84079 [details] [diff] [review]
Set 10ms as the min limit for JS timeouts

r=bzbarsky
Comment 27 Johnny Stenback (:jst, jst@mozilla.com) 2002-06-18 17:50:41 PDT
Comment on attachment 84079 [details] [diff] [review]
Set 10ms as the min limit for JS timeouts

Rick says sr=rpotts
Comment 28 Johnny Stenback (:jst, jst@mozilla.com) 2002-06-18 17:53:05 PDT
Fix checked in.
Comment 29 Jeremy M. Dolan 2002-06-20 16:02:26 PDT
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).
Comment 30 Wayne Mery (:wsmwk, NI for questions) 2009-03-17 04:05:47 PDT
*** Bug 148638 has been marked as a duplicate of this bug. ***

Note You need to log in before you can comment on or make changes to this bug.