From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Martin Stjernholm Newsgroups: gmane.emacs.devel Subject: Re: Are there plans for a multi-threaded Emacs? Date: Thu, 04 Dec 2003 00:38:04 +0100 Sender: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Message-ID: <5bad69zd43.fsf@lister.roxen.com> References: <87oevbes4h.fsf@emacswiki.org> <20031117040607.C6C5D79B72@server2.messagingengine.com> <87ekvpx18d.fsf@emptyhost.emptydomain.de> <4nad6cikxy.fsf@holmes.bwh.harvard.edu> <4nllpt3hr3.fsf@lockgroove.bwh.harvard.edu> NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: sea.gmane.org 1070494865 31611 80.91.224.253 (3 Dec 2003 23:41:05 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Wed, 3 Dec 2003 23:41:05 +0000 (UTC) Cc: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Thu Dec 04 00:41:02 2003 Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1ARgcA-000414-00 for ; Thu, 04 Dec 2003 00:41:02 +0100 Original-Received: from monty-python.gnu.org ([199.232.76.173]) by quimby.gnus.org with esmtp (Exim 3.35 #1 (Debian)) id 1ARgc9-0006wB-00 for ; Thu, 04 Dec 2003 00:41:02 +0100 Original-Received: from localhost ([127.0.0.1] helo=monty-python.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.24) id 1ARhZS-0006wB-6C for emacs-devel@quimby.gnus.org; Wed, 03 Dec 2003 19:42:18 -0500 Original-Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.24) id 1ARhXY-0006KK-Mg for emacs-devel@gnu.org; Wed, 03 Dec 2003 19:40:20 -0500 Original-Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.24) id 1ARhX1-0006Ay-7X for emacs-devel@gnu.org; Wed, 03 Dec 2003 19:40:18 -0500 Original-Received: from [194.52.182.190] (helo=mail.roxen.com) by monty-python.gnu.org with esmtp (Exim 4.24) id 1ARhWu-00069l-VB for emacs-devel@gnu.org; Wed, 03 Dec 2003 19:39:41 -0500 Original-Received: by mail.roxen.com (Postfix, from userid 52) id ADAD69B0D; Thu, 4 Dec 2003 00:38:12 +0100 (MET) Original-Received: from lister.roxen.com (lister.roxen.com [194.52.182.147]) by mail.roxen.com (Postfix) with ESMTP id A679D99D2; Thu, 4 Dec 2003 00:38:04 +0100 (MET) Original-Received: from mast by lister.roxen.com with local (Exim 3.36 #1 (Debian)) id 1ARgZI-0002mM-00; Thu, 04 Dec 2003 00:38:04 +0100 Original-To: Ted Zlatanov In-Reply-To: <4nllpt3hr3.fsf@lockgroove.bwh.harvard.edu> (Ted Zlatanov's message of "Wed, 03 Dec 2003 12:58:56 -0500") User-Agent: Gnus/5.090016 (Oort Gnus v0.16) Emacs/20.7 (gnu/linux) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.2 Precedence: list List-Id: Emacs development discussions. List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Xref: main.gmane.org gmane.emacs.devel:18342 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:18342 Ted Zlatanov wrote: > What I proposed is that *all* functions start with the "synchronous" > atribute. This would apply to primitives as well. > > Then, they would be gradually rewritten. For instance, a thread-safe > setq would act just like the regular setq, but it would lock its > arguments with semaphores before modifying them. The thread-safe > setq can then be marked "asynchronous." What about simply having a single mutex for everything? It's essentially always held, and a thread only relinquishes it to do blocking operations. Immediately afterwards it reacquires the lock. This way Emacs is still effectively single threaded (in the sense that only one thread runs at a time) but it is possible to use the threading paradigm to do blocking operations. It's comparatively easy to implement since all data access still goes on as usual. It's necessary to make the C level thread safe only in the small regions where the lock is released. I take it this would essentially be the same as your starting point, where all functions are synchronous - nothing runs at the same time as anything else. There are however only small benefits to go further: o To be able to run several threads simultaneously in multicpu or hyperthreaded systems. o To get OS level preemption between threads. Preemption can be simulated on the elisp level by making sure that no significant amount of code gets to run without relinquishing the lock. I.e. there is a function that gets called regularly that only releases the lock, yields (if the thread implementation supports it) and then takes the lock again. Another possibility is to do no preemption at all, and instead introduce an elisp function `yield' that does the above. CPU bound code should call it explicitly every once in a while. That has the nice property that other elisp code does not have to use locks to avoid preemption in sensitive areas. This means "old fashioned" cooperative multitasking, and malfunctioning code can still lock up everything, but that's not any worse than the situation today so I don't regard it as a significant problem. I see these benefits with this model compared to a "fully" multithreaded variant: o Fairly small changes in the C code. o No significant change in the elisp execution model, at least not if preemption is avoided. o Little overhead in locking - there's no fine grained locking on individual data structures.