[Top][All Lists]

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

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

From: Eli Zaretskii
Subject: Re: Emacs design and architecture. How about copy-on-write?
Date: Mon, 18 Sep 2023 20:47:31 +0300

> From: Ihor Radchenko <yantar92@posteo.net>
> Cc: acm@muc.de, incal@dataswamp.org, emacs-devel@gnu.org
> 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

Synchronous to what?

> (because of global redisplay lock)

What is the global redisplay lock?

> If multiple threads trigger redisplay with different scroll-margin
> values, it will be not different compared to the following example:

I understand the problem, I'm asking what could or should be the
possible solutions.

> > 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.

No, it just assumes that when working on a window, its buffer is
temporarily made the current buffer.  But since we already made the
current buffer per-thread, this is not a problem.  From thread.h:

    /* This points to the current buffer.  */
    struct buffer *m_current_buffer;
  #define current_buffer (current_thread->m_current_buffer)

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

This is a non-issue.  If we don't allow non-main threads interact with
the user, we can leave this code intact.  If we do allow interaction
from non-main threads, we just need to bind kboard-local variables to
their thread-specific values when we switch to the thread.

> 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.

That's completely irrelevant to the issue at hand.  The fact that
Emacs has a huge global state, and all of its code relies on that is a
separate issue.  Here, I asked you in what sense is xdisp.c's code
single-threaded; if your answer is "because of its reliance on global
state", it means there's no separate problem of xdisp.c that is based
on single thread.

And those of these global variables that aren't changing while some
thread is redisplaying a window showing a particular buffer don't even
interfere with parallel redisplay.

As for redisplay optimizations, they are entirely based on buffer- and
window-local information, so I cannot imagine why you think they will
be very fragile.

> 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.

Why do you expect that?

> >> 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.

No, it just means any such changes need to be communicated to other
"redisplaying" threads, so that they also restart.

reply via email to

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