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: Emacs design and architecture. How about copy-on-write? Date: Mon, 18 Sep 2023 20:47:31 +0300 Message-ID: <83cyyfe5l8.fsf@gnu.org> References: <83edizjn0v.fsf@gnu.org> <0518f65b-1dd1-6923-8497-da4d3aeac631@gutov.dev> <87sf7fc7kd.fsf@dataswamp.org> <834jjuk68t.fsf@gnu.org> <87cyyhc7uu.fsf@dataswamp.org> <83ttrsg9nx.fsf@gnu.org> <83h6nrg4eg.fsf@gnu.org> <83v8c7elan.fsf@gnu.org> <877conk5ny.fsf@localhost> <83ttrreeu0.fsf@gnu.org> <87bkdzeas1.fsf@localhost> Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="40321"; mail-complaints-to="usenet@ciao.gmane.io" Cc: acm@muc.de, incal@dataswamp.org, emacs-devel@gnu.org To: Ihor Radchenko Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Mon Sep 18 19:48:40 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 1qiIMS-000AIS-5o for ged-emacs-devel@m.gmane-mx.org; Mon, 18 Sep 2023 19:48:40 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qiILO-0000XS-Mb; Mon, 18 Sep 2023 13:47:34 -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 1qiILM-0000Wu-TQ for emacs-devel@gnu.org; Mon, 18 Sep 2023 13:47:33 -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 1qiILK-0000Vk-QR; Mon, 18 Sep 2023 13:47:30 -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=kK91vc1sbFLNTYNoKhXGqgyM7c9pjYmuAffzFEhgtAg=; b=R7SnwtTeTSOm xUfR5c9NTEdAQIgeRjsTIm9ccZ/a7MPI02Fbk9Jrr7qqCxiMxdcReTOe0tqQMcVzdNKOJPPtjUxgf U6jDhrJMfbCH5fhmUvv6PWdwKLdl5dEl0brYPItJROQzz7+6EILVCedwmdY8WVva1SELgqXT1wFm9 /lULXgMYVLzsPwQUK4i67AJX//6SvUPlAZV/5XLH/tzmFJCLbQPf9Ih3EGpWh8yP7e18G+6taqt7E z2A99unJYHnX/79Q0UIQ2h7Veo0mlVB5pRIB5eTBt17785MPe2iK6hh1thrXVoy+58Qtgd4RjEHDJ Zf37FnqyC9Gp6tlaO4TYNg==; In-Reply-To: <87bkdzeas1.fsf@localhost> (message from Ihor Radchenko on Mon, 18 Sep 2023 15:55:26 +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:310713 Archived-At: > From: Ihor Radchenko > Cc: acm@muc.de, incal@dataswamp.org, emacs-devel@gnu.org > Date: Mon, 18 Sep 2023 15:55:26 +0000 > > Eli Zaretskii 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.