From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Eli Zaretskii Newsgroups: gmane.emacs.devel Subject: Re: Concurrency via isolated process/thread Date: Sun, 09 Jul 2023 14:59:16 +0300 Message-ID: <83o7kl9tyj.fsf@gnu.org> References: <871qhnr4ty.fsf@localhost> <877crd6w53.fsf@localhost> <877crdjiwn.fsf@yahoo.com> <874jmh6v4s.fsf@localhost> <83y1jtgmbw.fsf@gnu.org> <87zg49xfke.fsf@localhost> <83sfa1gjns.fsf@gnu.org> <87r0plxbep.fsf@localhost> <83ilawhpi6.fsf@gnu.org> <87zg48apwr.fsf@localhost> <83edljg8ub.fsf@gnu.org> <87o7knbxr7.fsf@localhost> <838rbrg4mg.fsf@gnu.org> <87ilavbvdr.fsf@localhost> <834jmffvhy.fsf@gnu.org> <878rbrbmwr.fsf@localhost> <83fs5zecpo.fsf@gnu.org> <87351zbi72.fsf@localhost> <83351yevde.fsf@gnu.org> <87cz12ad2w.fsf@localhost> <83a5w6cwdr.fsf@gnu.org> <87pm518m0g.fsf@localhost> Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="24268"; mail-complaints-to="usenet@ciao.gmane.io" Cc: luangruo@yahoo.com, emacs-devel@gnu.org To: Ihor Radchenko Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sun Jul 09 13:59:58 2023 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qIT54-00066R-HL for ged-emacs-devel@m.gmane-mx.org; Sun, 09 Jul 2023 13:59:58 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qIT4J-0001jq-TV; Sun, 09 Jul 2023 07:59:11 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qIT4I-0001jK-4N for emacs-devel@gnu.org; Sun, 09 Jul 2023 07:59:10 -0400 Original-Received: from fencepost.gnu.org ([2001:470:142:3::e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qIT4H-0006Vz-Ry; Sun, 09 Jul 2023 07:59:09 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=gnu.org; s=fencepost-gnu-org; h=References:Subject:In-Reply-To:To:From:Date: mime-version; bh=gMpJqsJsz6DhNUMWpiQRcLzIq6os4v/R7h75BynWlqU=; b=HG5y5cJrJGw1 DrBL2LCaQOJUY1D80w6C1n1LcsV5EGKDGNJkdmRYVSl/+kU0CgSaDM7Y2cD0EALa3/B2KVZMnYyIi eZy+RiCdxEhSlhlf3dgeYu7G2u248ta6LP7ZE5VDBhMKWwz+bksmgQXsBgZ8YNhYAycrXrJKnrHtS /vcVeDrRBPZ6alcgQqFu1hX/iRMU7MZ9H0Ir5S/ELOmEBcBzQVf+Nb5/9piND4/1hCNk8KVrkLt8l rKJ69sB/PXb+Mo4DLskCxQyC9YgcIjO7hyFABv4uKtwe45eYNcVgW/bjIEKfNz2ChMqRvAky4mEft yg/Q9C3JPCOzXmNpMns/KA==; Original-Received: from [87.69.77.57] (helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qIT4H-0002xN-55; Sun, 09 Jul 2023 07:59:09 -0400 In-Reply-To: <87pm518m0g.fsf@localhost> (message from Ihor Radchenko on Sun, 09 Jul 2023 09:36:15 +0000) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.devel:307665 Archived-At: > From: Ihor Radchenko > Cc: luangruo@yahoo.com, emacs-devel@gnu.org > Date: Sun, 09 Jul 2023 09:36:15 +0000 > > Eli Zaretskii writes: > > >> > Which variables can safely and usefully be made thread-local? > >> > >> PT, ZV, BEGV > > > > Even that is not enough: you forgot the gap. > > Am I missing something, does the gap remain intact when the just move > point? AFAIU, the gap only needs to move when we do edits. That's not the issue. The issue is that without the gap being accurate Emacs cannot convert buffer positions to pointers to buffer text. So not saving the gap is asking for trouble. Once again: please do NOT try designing Emacs features based on what you happen to see in the current code. First, it is easy to miss important stuff that invalidates your design; and second, code does change over time, and if you introduce a feature that assumes some changes will never happen, you are introducing ticking time bombs into Emacs. So instead, you need to understand the assumptions and the invariants on which the code relies, and either keep them or go over everything and adapt the code to assumptions that are no longer true. In this case, the assumption is that the gap is always accurate except for short periods of time, during which buffer text cannot be accessed via buffer positions. > I was thinking about thread-local variables just to move around and read > buffer. You will see in xml.c that we move the gap even though we do not "edit" (i.e. do not modify the buffer). We do this so that a pointer to a portion of buffer text could be passed to an external library as a simple C char array -- a legitimate technique that must be available. So even reading the buffer sometimes might require moving the gap. > Asynchronous writing is probably a poor idea anyway - the very > idea of a gap does not work well when we need to write in multiple > far-away places in buffer. What if the main thread modifies buffer text, while one of the other threads wants to read from it? > >> and the buffer-local variables that are represented by the > >> global C variables. > > > > That's a lot! > > Do you mean that "a lot" is bad? Yes, because it will require a huge thread-local storage. > >> > I don't see how this could be practically useful. > >> > >> For example, `org-element-interpret-data' converts Org mode AST to > >> string. Just now, I tried it using AST of one of my large Org buffers. > >> It took 150seconds to complete, while blocking Emacs. > > > > It isn't side-effect-free, though. > > It is, just not declared so. No, it isn't. For starters, it changes obarray. > >> Yes. I mean... look at Haskell. There is no shortage of pure functional > >> libraries there. > > > > I cannot follow you there: I don't know Haskell. > > In short, pure functions in Haskell can utilize multiple CPUs > automatically, without programmers explicitly writing code for > multi-threading support. > https://wiki.haskell.org/Parallelism Thanks, but I'm afraid this all is a bit academic. Haskell is a language, whereas Emacs is a text-processing program. So Emacs doesn't only define a programming language, it also implements gobs of APIs and low-level subroutines whose purpose is to facilitate a specific class of applications. The huge global state that we have is due to this latter aspect of Emacs, not to the design of the language. > > ... More importantly, when you call some function from > > simple.el, how do you know whether all of its subroutines and > > primitives are 'pure'? > > We do not, but it may be possible to add assertions that will ensure > purity in whatever sense we need. Those assertions will fire in any useful program with 100% certainty. Imagine the plight of an Emacs Lisp programmer who has to write and debug such programs. We have in Emacs gazillion lines of Lisp code, written, debugged, and tested during 4 decades. We use those, almost without thinking, every day for writing Lisp programs. What you suggest means throwing away most of that and starting from scratch. I mean, take the simplest thing, like save-buffer-excursion or with-selected-window, something that we use all the time, and look how much of the global state they access and change. Then imagine that you don't have these and need to write programs that switch buffers and windows temporarily in thread-safe way. Then reflect on what this means for all the other useful APIs and subroutines we have.