[Date Prev][Date Next][Thread Prev][][Date Index][Thread Index]

Re: w3m tab line constantly consumes CPU

In [emacs-w3m : No.12198] Michael Heerdegen wrote:
> From time to time, I see Emacs constantly consuming CPU, ca. 10%.  Emacs
> doesn't hang, but consumes enough CPU to let my ventilator run all the
> time.

> It took some time to identify that w3m was the culprit, its tab line,
> to be more precise.  When the tab line is visible, `w3m-tab-line' and
> `w3m-force-window-update' are constantly run, ca. 10 times per second.
> Use `trace-function' to verify.

Yes, I knew the tab line eats CPU not a little.  I also tried `elp':

M-x elp-instrument-package RET w3m RET
Run emacs-w3m for a while...
M-x elp-results RET
(If necessary, do `M-x elp-reset-all RET' to reset the result.)

According to the result, `w3m-tab-line' and `w3m-force-window-update'
seem to waste time not so much.  So, I was thinking we have nothing
to have to do if those appetites don't grow anymore.

> Why does that happen?  Actually, it is a loop.  The w3m header line has
> this format:

>   (:eval (w3m-tab-line))

This would be the most convenient way to update the appearance of
the header line (or the mode line).  But, in fact, we don't know
how frequent it runs or how greedy it eats CPU.  What I know is
only that it seems due to the Emacs internals.

> And this is what I think loops:

> 1. The w3m header-line (the tab line) is redisplayed.
> 2. `w3m-tab-line' is called.  The code contains

>   (run-at-time 0.1 nil
> 		     (lambda (buffer)
> 		       (when (buffer-live-p buffer)
> 			 (with-current-buffer buffer
> 			   (setq w3m-tab-timer nil)
> 			   (inline (w3m-force-window-update)))))
> 		     current)

When I added it for the first time, the timer function did only:
(setq w3m-tab-timer nil)
This aimed to make what the `w3m-tab-line' function does minimal,
except for updating the header line it does per 0.1 sec.  It was
enough for Emace 20.90~21.x, however the header line got not to
necessarily be updated thereafter.  (But now, it looks like going
well again without `w3m-force-window-update' at least for Emacs

>   so

> 3. So, after 0.1 seconds, `w3m-force-window-update' is called.  This redraws
>    the window's header line, too, so we are back to 1.  Ouch!

> I don't want to make a suggestion on how to fix this because I don't
> know the code well.  We have to avoid the loop somehow.

As you might think, another way to update the header line would
be to make it event-driven.  That is, to modify all the functions,
that change the header line appearance, so as to call `w3m-tab-line'
if and only if it is necessary.