Subject: bug#75922: CPU hogs with pgtk

From: Nicolas Sarlin <[email-masked]>
Date: Wed, 29 Jan 2025 23:30:55 +0100

On Wed, Jan 29, 2025, 18:29 Pip Cet <[email-masked]> wrote:

> "Nicolas Sarlin" <[email-masked]> writes:
>
> > On Wed, 29 Jan 2025 at 14:06, Eli Zaretskii <[email-masked]> wrote:
> >>
> >> > From: Nicolas Sarlin <[email-masked]>
> >> > Date: Wed, 29 Jan 2025 12:05:16 +0100
> >> >
> >> > I'm using lsp-mode with corfu on the emacs-30 branch, and I get
> extremely
> >> > frequent CPU hogs (CPU runs at 100% for a few seconds) while typing
> >> > code. I report this as an emacs bug because it seems to only occurs
> when
> >> > emacs is compiled with pgtk. If I rebuild emacs with "make bootstrap
> >> > configure=default" the bug disapears.
> >> >
> >> > Here is a profiler record:
> >> >        11152  91% - corfu--post-command
> >> >        11152  91%  - corfu--exhibit
> >> >        11043  90%   - corfu--update
> >> >        10891  88%    - corfu--recompute
> >> >        10891  88%     - corfu--filter-completions
> >> >        10891  88%      - completion-all-completions
> >> >        10891  88%       - completion--nth-completion
> >> >        10891  88%        - seq-some
> >> >        10891  88%         - seq-do
> >> >        10891  88%          - mapc
> >> >        10891  88%           - #<byte-code-function AC1>
> >> >        10891  88%            - #<byte-code-function AD0>
> >> >        10891  88%             -
> lsp-completion-passthrough-all-completions
> >> >        10891  88%              - #<byte-code-function 4B5>
> >> >        10891  88%               - #<byte-code-function 4DE>
> >> >        10888  88%                - lsp-request-while-no-input
> >> >        10888  88%                 - sit-for
> >>
> >> The profile says most of the time is spent in sit-for called from
> >> lsp-request-while-no-input.  First, sit-for is not supposed to consume
> >> CPU, because it's a waiting function.  Are you sure this profile was
> >> taken when Emacs was hogging CPU?
> >>
> >> And second, lsp-mode is not part of Emacs, so if indeed the above is a
> >> profile representative of high CPU load, I suggest to report this to
> >> the developers of lsp-mode first, even though the problem appears only
> >> in the PGTK build.
> >>
> >> Thanks.
> >
> > Hi, thank you for your answer.
> > Yes, this profile was collected during an emacs freeze. It took me a
> > few second (maybe 10) after `profiler-start` to trigger the freeze,
> > then again a few seconds of freeze, then I ran `profiler-stop`
> > directly after. During the freeze I had one CPU core constantly
> > running at 100%.
>
> My guess is it's this code in lsp-mode.el:
>
>               (while (not (or resp-error resp-result (input-pending-p)))
>                 (catch 'lsp-done
>                   (sit-for
>                    (if expected-time (- expected-time send-time) 1)))
>                 (setq send-time (float-time))
>                 (when (and expected-time (< expected-time send-time))
>                   (error "Timeout while waiting for response.  Method: %s"
> method)))
>
> This code appears to want to reliquish the CPU for the next
> lsp-response-timeout (default 10) seconds, so it calls sit-for with an
> argument close to 10.0, or 1 if no timeout is set.
>
> The behavior of sit-for is to return immediately if there is pending
> input, ignoring the timeout argument.
>
> In this case, this loop will use all of the CPU until whatever it is
> actually waiting for happens, assuming a single "input event" (a
> keypress is one, but certain kinds of mouse movement or a similar event
> can also cause sit-for to exit immediately) has happened.
>
> Some other places also in that file may work less than optimally when
> sit-for returns immediately, also.
>
> So this seems most likely like a bug there, and it may be triggered more
> by pgtk/wayland because of such details as key repeat being handled by
> the application rather than what used to be the X server.
>
> I'm slightly surprised at your perf report, but at least the last part
> doesn't seem inconsistent with that interpretation.
>
> Once the bug is fixed, it would be great to hear how the documentation
> of sit-for could be improved.  If that doesn't work, we might even want
> to detect situations in which sit-for is called repeatedly with a
> timeout argument even though no input was handled in the meantime.
>
> Pip

Thank you for your help! I will report it to lsp-mode with the info you
provided.

Sorry for the disturbance