Subject: Re: bug#75922: CPU hogs with pgtk

From: Pip Cet <[email-masked]>
Date: Thu, 30 Jan 2025 08:48:12 +0000

"Nicolas Sarlin" <[email-masked]> writes:

> 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

No problem at all. I think the API is a bit confusing, and the
documentation doesn't warn about it sufficiently.  Both can be changed.

Pip