emacs-devel
[Top][All Lists]
Advanced

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

Re: Emacs design and architecture. How about copy-on-write?


From: Ihor Radchenko
Subject: Re: Emacs design and architecture. How about copy-on-write?
Date: Mon, 18 Sep 2023 15:55:26 +0000

Eli Zaretskii <eliz@gnu.org> writes:

>> IMHO, the only sane way to utilize the existing redisplay is redisplay
>> lock - only one thread can request redisplay at a time, using its
>> thread-local state.
>
> So if one thread changes scroll-margin and triggers redisplay, then
> another thread triggers redisplay with its (different value of
> scroll-margin), the display will scroll or move point back? and then
> forward again? and then back again?

Nope. I consider that redisplay is always synchronous (because of global
redisplay lock). If multiple threads trigger redisplay with different
scroll-margin values, it will be not different compared to the following
example:

(let ((scroll-margin 500)) (redisplay))
<...>
(redisplay)
<...>
(let ((scroll-margin 10)) (redisplay))
<...>

A better illustration is probably

(progn
  (let ((bidi-paragraph-direction 'right-to-left)) (redisplay))
  (sleep-for 1)
  (redisplay)
  (sleep-for 1)
  (let ((bidi-paragraph-direction 'right-to-left)) (redisplay))
  (sleep-for 1))

>> >> I don't think several redisplay threads would be a good idea - usually,
>> >> there is just one screen Emacs is drawing on.
>> >
>> > It's one screen, but each window is redrawn separately (on GUI
>> > terminals).
>> 
>> Technically yes, but AFAIU the code is written assuming single-threaded
>> execution.
>
> In what way does it assume single-threaded execution?  We walk the
> window tree of a frame and redisplay each leaf window in the tree,
> that's all.  Maybe I don't understand what you mean by "assuming
> single-threaded execution".

1. xdisp assumes at its core logic that current_buffer is always a
   single buffer. And it affects, for example mode-line faces.

2. `display_mode_line' uses global temporary override by calling
   `push_kboard'. AFAIU, it is also relying on single-threaded code.

3. xdisp is relying on a number of global-only variables like
   `mode-line-compact', `show-trailing-whitespace', and similar.
   AFAIR, things like `show-trailing-whitespace' affect how the
   optimizations are applied when deciding which windows should be
   redisplayed and which should not. I suspect that logic related to
   optimizations may be very fragile with async execution.

4. There are complex interactions between window redisplay, mode lines,
   echo area, and toolbars. AFAIR, if some Elisp (or maybe C) code,
   recursively called during window redisplay, affects mode-line/toolbar
   height, xdisp restarts (sometimes, partially) the redisplay process.
   I expect issues when this interacts with async redisplay of
   individual windows.

>> Decoupling redisplay of different windows would require significant
>> non-trivial changes in xdisp.c
>
> In which part(s) of xdisp.c?  Most of xdisp.c handles redisplay of a
> single window.

Yup, but see (4). I recall seeing a number of non-trivial `goto' calls
where faces or window geometry are checked for changes and redisplay has
to redo redisplay according to the changed values. When such geometry
changes can also happen asynchronously, a number of places in the code
that assumed fixed geometry and glyph matrix may be broken.

-- 
Ihor Radchenko // yantar92,
Org mode contributor,
Learn more about Org mode at <https://orgmode.org/>.
Support Org development at <https://liberapay.com/org-mode>,
or support my work at <https://liberapay.com/yantar92>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]