emacs-devel
[Top][All Lists]
Advanced

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

Re: Concurrency via isolated process/thread


From: Ihor Radchenko
Subject: Re: Concurrency via isolated process/thread
Date: Fri, 07 Jul 2023 15:17:23 +0000

Eli Zaretskii <eliz@gnu.org> writes:

>> maybe need to have multiple heaps.
>
> All modern implementation of malloc already do use several different
> heaps internally.

I was talking about Elisp heaps.
AFAIU, Elisp memory management is conceptually single-threaded.

>> I was only able to identify the following:
>> 
>> interrupt_input_blocked
>> current_buffer
>> last_known_column_point
>
> There are much more:
>
>   buffer-alist

I do not see how this is a problem to lock/unlock this variable.

>   buffer's base-buffer

I do not see it. May you point me to where this is changed?

>   buffer's undo-list

That's just a synchronization between old_buffer and
old_buffer->base_buffer.
I am not 100% sure why it is necessary to be done this way and manually
instead of making undo-list values in indirect buffers point to base
buffer.

>   buffer's point and begv/zv markers

AFAIU, these store the last point position and narrowing state.
I do not see much problem here, except a need to lock these variables
while writing them. They will not affect PT, BEGZ, and ZV in other
threads, even if those operate on the same buffer now.

>   buffer's marker list

May you point me where it is?

>   buffer's local variables

I admit that I do not understand what the following comment is talking
about:

  /* Look down buffer's list of local Lisp variables
     to find and update any that forward into C variables.  */

>> AFAIU, current_buffer might be made thread-local and
>> last_known_column_point can be made buffer-local.
>
> The current buffer is already thread-local.

Thanks for the pointer. I did not expect
#define current_buffer (current_thread->m_current_buffer)

>> interrupt_input_blocked is more tricky. But it is just one global state
>> variable. Surely we can find a solution to make it work with multiple 
>> threads.
>
> Yes, but we have just looked at a single primitive: set-buffer.  Once
> in the buffer, any useful Lisp program will do gobs of stuff, and each
> one of those accesses more and more globals.  How do you protect all
> that in a 100% reliable way? by identifying the variables and
> structures one by one? what if tomorrow some change in Emacs adds one
> more?

This sounds like a problem that is already solved by any program that
uses async threads. Maybe Po Lu can provide good insights.

>> > I think you misunderstand the frequency of such collisions.
>> > case-fold-search comes to mind.
>> 
>> How so? What is the problem with a buffer-local variable that is rarely
>> set directly (other than by major modes)? let-binding is common, but it
>> is not a problem.
>
> Searching for "setq case-fold-search" finds more than 30 hits in Emacs
> alone.  And this variable is just an example.

These are mostly major/minor modes and constructs like

(setq case-fold-search ...)
(do staff)
(setq case-fold-search old-value)

The last one is legitimate problem with logic. Although not much
different from Elisp threads doing the same and changing buffer-local
variables in the midst of other thread running in the same buffer.
So, I do not see how this should prevent async threads. We just need to
take care about setq not attempting to write into buffer-local variables
at the same time, which is solved by locking.

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