Subject: bug#45898: 27.1; wedged in redisplay again

From: Eli Zaretskii <[email-masked]>
Date: Mon, 13 Jun 2022 15:57:59 +0300

> From: Lars Ingebrigtsen <[email-masked]>
> Cc: [email-masked],  [email-masked]
> Date: Mon, 13 Jun 2022 14:10:19 +0200
> 
> Eli Zaretskii <[email-masked]> writes:
> 
> > Here's the first cut.  It still needs polishing and some testing, but
> > let me know what you think:
> 
> [...]
> 
> > +/* Update the redisplay-tick count for a window, and signal an error
> > +   if the tick count is above some threshold, indicating that
> > +   redisplay of the window takes "too long".
> 
> Ah, instead of measuring the time elapsed, we use the number of iterator
> "executions" as a proxy.  That sounds promising.

Yes.  That idea came up while discussing this with Gerd Möllmann, btw.
It's much simpler than measuring time (which would require
high-resolution timing, which is much less portable and more tricky to
get right, what with modern systems constantly adjusting their time).

> One problem that occurs to me is if you're, say, only displaying a shell
> buffer, and it's outputting data -- then I don't think we'll be changing
> windows, but just accruing ticks?  But I think that should be easy
> enough to fix, since we'll be returning to command_loop and we could
> just have that nixing out the tick count, too.  Probably.

Yes, zeroing out the count when redisplay is done is probably a good
idea.  It's on my todo, probably in mark_window_display_accurate_1 or
thereabouts.  The only consideration here is that a successful
redisplay of a window could be followed by something like
vertical-motion across the same window, which could take "too long",
and we perhaps want the counters to be accumulated.  Hmm...

(Actually, output in a shell buffer is not a problem, because comint
calls 'recenter' very frequently, at least by default, and 'recenter'
resets the ticks count.  But maybe there are other situations where
this isn't guaranteed to happen.  So yeah, maybe command_loop is a
better place.)

> A different problem is when we don't have many ticks, but each tick
> takes a long time to execute.  The classic problem here is when we have
> a font-locking regexp that's very complicated (with lots of
> backtracking).  Then we don't update anything on the screen much -- we
> spend (virtually) all the time in the regexp matcher.  I don't see an
> easy fix to that using this scheme...

That's why update_redisplay_ticks accepts its first argument, instead
of always adding 1: I thought about some potentially expensive
operations that could be either more or less expensive than just
processing a single character.  E.g., font-lock calls regexp matching,
so we should try to come up with some measure of its "expensiveness"
based on...something.  This will need some tuning, but all we need is
some coarse correlation.

> > For testing purposes, is it possible to have examples of files that
> > could benefit from this feature, i.e. files where Emacs becomes not
> > responsive enough?  I'm not sure the few examples I have cover all the
> > popular reasons for the slowness, as I think there are more than one
> > or two.
> 
> I don't have anything handy...  anybody else have a setup that will
> freeze Emacs redisplay that we can test with?

"Freeze" is not actually a requirement; it's enough if Emacs's
responses become very slow.  For now, I used the file described here:

  https://lists.gnu.org/archive/html/help-gnu-emacs/2022-05/msg00070.html

But it is only one kind of such files.  Perhaps Phil could point me to
additional examples; added to CC.