* Threads in emacs implementation
@ 2005-06-07 2:22 Denis Bueno
2005-06-07 2:52 ` Miles Bader
` (2 more replies)
0 siblings, 3 replies; 37+ messages in thread
From: Denis Bueno @ 2005-06-07 2:22 UTC (permalink / raw)
Hi all,
Compared to many of the people who contribute to this list, I'm an
unsophisticated emacser. I know that an enormous amount of intelligent
development has been put into GNU/Emacs over the years, and I don't
want to slight that.
Having said that, my question is, has thought been put into
multithreading parts of Emacs? Or exposing a rudimentary threading API
to Emacs Lisp? This could easily devolve into a war about threading
apis, but, just support some simple subset of pthreads would work.
The background for my question: In Gnus, certain network operations
often take a long time -- sometimes I don't want to check my email
when it prompts me for a password, but I hit Return anyway, causing
Emacs to visibly hang for a minute or two. Sometimes whatever server
Gnus wants is down (or DNS is down, or whatever), and it 'hangs' until
it's timed out. This downtime is in many cases at least long enough
that I could profitably be doing work in other Emacs buffers.
This downtime is probably experienced in other network modes in Emacs
(like Tramp, I suspect, although I don't personally use it).
So, why is Emacs single-threaded? What issues have been considered wrt
having a multithread api in Emacs lisp?
Thanks for Emacs as it is! I can't program without it.
-Denis
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-07 2:22 Denis Bueno
@ 2005-06-07 2:52 ` Miles Bader
2005-06-07 2:59 ` Denis Bueno
2005-06-07 5:16 ` Ken Raeburn
2005-06-08 18:01 ` Magnus Henoch
2 siblings, 1 reply; 37+ messages in thread
From: Miles Bader @ 2005-06-07 2:52 UTC (permalink / raw)
Cc: emacs-devel
On 6/7/05, Denis Bueno <dbueno@gmail.com> wrote:
> Having said that, my question is, has thought been put into
> multithreading parts of Emacs?
Yes. It's very hard, because Emacs has lots and lots of global state
and lots and lots of code that doesn't expect to deal with threading
issues. Writing multi-threaded code from scratch isn't all that hard,
but making an existing massive code-base thread-safe is a very
different thing.
A search of the mailing list archives for emacs-devel should turn up
something I think.
-Miles
--
Do not taunt Happy Fun Ball.
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-07 2:52 ` Miles Bader
@ 2005-06-07 2:59 ` Denis Bueno
2005-06-07 4:26 ` Miles Bader
0 siblings, 1 reply; 37+ messages in thread
From: Denis Bueno @ 2005-06-07 2:59 UTC (permalink / raw)
Cc: emacs-devel
On 6/6/05, Miles Bader <snogglethorpe@gmail.com> wrote:
> On 6/7/05, Denis Bueno <dbueno@gmail.com> wrote:
> > Having said that, my question is, has thought been put into
> > multithreading parts of Emacs?
>
> Yes. It's very hard, because Emacs has lots and lots of global state
> and lots and lots of code that doesn't expect to deal with threading
> issues. Writing multi-threaded code from scratch isn't all that hard,
> but making an existing massive code-base thread-safe is a very
> different thing.
>
> A search of the mailing list archives for emacs-devel should turn up
> something I think.
I tried that, but, searching for 'thread' in a huge database of
mailing list 'threads' is not as useful as one might think. =]
Is there one conversation in particular you are thinking of?
-Denis
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-07 2:59 ` Denis Bueno
@ 2005-06-07 4:26 ` Miles Bader
0 siblings, 0 replies; 37+ messages in thread
From: Miles Bader @ 2005-06-07 4:26 UTC (permalink / raw)
Cc: emacs-devel
Denis Bueno <dbueno@gmail.com> writes:
> I tried that, but, searching for 'thread' in a huge database of
> mailing list 'threads' is not as useful as one might think. =]
>
> Is there one conversation in particular you are thinking of?
Yes; the following Google search yields many good first-page hits,
including the thread I remember:
site:gnu.org emacs multi-threaded
-Miles
--
`Cars give people wonderful freedom and increase their opportunities.
But they also destroy the environment, to an extent so drastic that
they kill all social life' (from _A Pattern Language_)
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-07 2:22 Denis Bueno
2005-06-07 2:52 ` Miles Bader
@ 2005-06-07 5:16 ` Ken Raeburn
2005-06-07 10:37 ` Nic Ferrier
2005-06-08 12:02 ` Richard Stallman
2005-06-08 18:01 ` Magnus Henoch
2 siblings, 2 replies; 37+ messages in thread
From: Ken Raeburn @ 2005-06-07 5:16 UTC (permalink / raw)
Cc: emacs-devel
On Jun 6, 2005, at 22:22, Denis Bueno wrote:
> Having said that, my question is, has thought been put into
> multithreading parts of Emacs? Or exposing a rudimentary threading API
> to Emacs Lisp? This could easily devolve into a war about threading
> apis, but, just support some simple subset of pthreads would work.
I've thought about it, yes.
As Miles said, there's a lot of global state, and lots of code that
doesn't expect threading issues. Indeed, the basic Lisp system itself
would need changes to deal with any sort of preemptive threading
system; dynamic bindings are currently implemented by overwriting a
symbol's value, and keeping track on the stack of what value needs to
be restored later. Garbage collection also gets more interesting when
multiple threads are manipulating Lisp objects at a time. (One could
go with fully cooperative threads, but then you still have to rewrite
all your I/O to be non-blocking, you lose any benefits of
multi-threading in third-party library code that might block, can't
take any advantage of multiple CPUs, etc.)
For various reasons, I decided to put my attention about three years or
so ago into a somewhat different project -- making it possible to run
Emacs with the Guile interpreter tied into the Lisp system. Guile --
GNU's Ubiquitous Intelligent Language for Extension -- is the GNU
Project's Scheme implementation, intended to be a general extension
language for the GNU Project. Scheme is Lisp-like in some ways,
different in others; in particular, Scheme uses static scoping, so Lisp
dynamic bindings are an interesting part of the issue. But there are
people working on making Guile be able to handle Emacs Lisp, and there
already is pthread support in Guile. So my thinking is, if the Emacs
Lisp engine can be made to operate on Guile objects (including, for
example, a new Guile object type that represents an Emacs buffer, which
is a Lisp type now), and these other people find ways to deal with
threads and dynamic scoping, then we've made a lot of progress not just
towards the possibility of multiple threads in Emacs, but also towards
having GNU's "ubiquitous extension language" available in what's
probably GNU's most commonly extended (and most extensible) program.
(There would be other effects also, like having one *massive*
application stress-testing the heck out of the Guile allocator and GC
system. Might be good for Guile in the long run, but I suspect the
initial performance might not be as good as what Emacs has already;
then again, I might be pleasantly surprised. There's a research
project out there on translating Lisp to Scheme and determining when
you might be able to optimize out the whole dynamic-binding mess and
use local values, which may translate to more efficient code. If Emacs
buffers can be made into an independent object type, perhaps other GNU
programs can incorporate them via Guile extensions. Guile has compiled
regular expressions as their own type; wouldn't it be nice if Gnus
article splitting could cache all of the compiled regular expressions
it uses even when GC runs, instead of just some number compiled in to
search.c?)
I started doing some work on isolating the Lisp system from the rest of
Emacs -- removing some assumptions here and there about how Lisp
objects were constructed, that sort of thing. But then I got
sidetracked with pesky things like work, wow, probably a couple of
years ago now, and wasn't able to make much progress for a long time.
(Unicode branch guys -- I'm sorry I never got that merge to your branch
done that was discussed back then, but by the time anyone got back to
me saying "yes", I was already too hosed to pay attention.) I've
managed to get some more time to put into it recently, but (a) I've
changed jobs and need to re-file some of the paperwork for donating
code, and (b) there's been talk of some kind of code freeze or at least
feature freeze, though I haven't been able to keep up on the mail quite
enough to know what the state of things is. So, I'm not sending in any
code changes yet. (And haven't got a lot of them yet anyways.)
That sort of work is relatively easy (even if sometimes spread through
lots of code -- the widespread changes are usually simple and
mechanical), and contributes in some ways towards keeping the code
cleaner outside of the guts of the Lisp engine itself.
Should we go all the way and actually replace the Lisp object
representation with something based on Guile? Some people say yes,
some people say absolutely not. Some think we should be rewriting
Emacs into some other language. Me, I just want to get something that
works, maybe fix some bugs in Guile and in Emacs that might be found in
the process, and then see where things stand...
Even if that happens, I have only put a little thought into what the
Emacs Lisp interface for threads would probably look like. Actually,
unless someone comes up with a more friendly wrapper package, I suspect
the interface would look a lot like the Scheme interface in Guile --
thread creation, mutex locks, condition variables, etc. Plus, I would
guess, locks in objects like buffers, windows, and frames to keep them
from getting corrupted. Message passing, work queue management, and so
forth could be built on top of the primitives without too much
difficulty, in either Lisp or Scheme. I think I'd be more concerned
about the UI -- we probably don't want two threads vying for user input
and stealing characters from one another or something. And, of course,
all that global state Miles was talking about...
(Note, too, that once you start using pthreads, you get new
restrictions on maximum stack depth, things like that; it can't grow
unbounded. That translates directly into a limit on the depth of Lisp
function calls, not by number, but by C stack frame size.)
> The background for my question: In Gnus, certain network operations
> often take a long time -- sometimes I don't want to check my email
> when it prompts me for a password, but I hit Return anyway, causing
> Emacs to visibly hang for a minute or two. Sometimes whatever server
> Gnus wants is down (or DNS is down, or whatever), and it 'hangs' until
> it's timed out. This downtime is in many cases at least long enough
> that I could profitably be doing work in other Emacs buffers.
This, in fact, was my motivation for thinking about it. But, I was
also doing a little hacking on Guile at the same time, and, well, I'm
sure some would say it was all downhill from there....
Ken
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-07 5:16 ` Ken Raeburn
@ 2005-06-07 10:37 ` Nic Ferrier
2005-06-08 12:02 ` Richard Stallman
1 sibling, 0 replies; 37+ messages in thread
From: Nic Ferrier @ 2005-06-07 10:37 UTC (permalink / raw)
Cc: emacs-devel
Ken Raeburn <raeburn@raeburn.org> writes:
> For various reasons, I decided to put my attention about three years or
> so ago into a somewhat different project -- making it possible to run
> Emacs with the Guile interpreter tied into the Lisp system. Guile --
> GNU's Ubiquitous Intelligent Language for Extension -- is the GNU
> Project's Scheme implementation, intended to be a general extension
> language for the GNU Project. Scheme is Lisp-like in some ways,
> different in others; in particular, Scheme uses static scoping, so Lisp
> dynamic bindings are an interesting part of the issue. But there are
> people working on making Guile be able to handle Emacs Lisp, and there
> already is pthread support in Guile. So my thinking is, if the Emacs
> Lisp engine can be made to operate on Guile objects (including, for
> example, a new Guile object type that represents an Emacs buffer, which
> is a Lisp type now), and these other people find ways to deal with
> threads and dynamic scoping, then we've made a lot of progress not just
> towards the possibility of multiple threads in Emacs, but also towards
> having GNU's "ubiquitous extension language" available in what's
> probably GNU's most commonly extended (and most extensible) program.
A couple of times I've thought about just linking guile and emacs
together, giving guile some wrappers around existing emacs types and
adding some mechanism to emacs for running guile programs.
I figured that such a system would be a very slow evolutionary step
and probably more likely to succeed in the long run (10 years?) than
just trying to switch over.
Unfortunately, guile is not a small, well designed program. It is much
more of a mess than emacs is and looks hard to put in nicely. Putting
it in crassly is still an option though.
Nic
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
@ 2005-06-08 8:24 tomas
0 siblings, 0 replies; 37+ messages in thread
From: tomas @ 2005-06-08 8:24 UTC (permalink / raw)
[-- Attachment #1.1: Type: text/plain, Size: 539 bytes --]
Nic Ferrier writes:
> A couple of times I've thought about just linking guile and emacs
> together, giving guile some wrappers around existing emacs types and
> adding some mechanism to emacs for running guile programs.
There was a working prototype a couple of years ago by Keisuke Nishida
(of Guile-VM fame). See, for example
<http://lists.gnu.org/archive/html/guile-devel/2001-04/msg00412.html>
It looked very promising (as did Guile-VM); but I don't know the whereabouts
of this bright person.
Regards
-- tomas
[-- Attachment #1.2: Type: application/pgp-signature, Size: 189 bytes --]
[-- Attachment #2: Type: text/plain, Size: 142 bytes --]
_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-07 5:16 ` Ken Raeburn
2005-06-07 10:37 ` Nic Ferrier
@ 2005-06-08 12:02 ` Richard Stallman
1 sibling, 0 replies; 37+ messages in thread
From: Richard Stallman @ 2005-06-08 12:02 UTC (permalink / raw)
Cc: dbueno, emacs-devel
Garbage collection also gets more interesting when
multiple threads are manipulating Lisp objects at a time.
In Emacs, GC doesn't have to happen at any particular point.
It is done as a regular housekeeping task.
So it could work well enough to set a flag telling all threads to wait
once they come to a suitable stopping point, and GC once all threads
get there.
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-07 2:22 Denis Bueno
2005-06-07 2:52 ` Miles Bader
2005-06-07 5:16 ` Ken Raeburn
@ 2005-06-08 18:01 ` Magnus Henoch
2005-06-08 19:52 ` Nic Ferrier
2005-06-09 14:40 ` Richard Stallman
2 siblings, 2 replies; 37+ messages in thread
From: Magnus Henoch @ 2005-06-08 18:01 UTC (permalink / raw)
I've been thinking about using GNU pth to implement threads in Emacs.
GNU pth only does cooperative threading, and has special non-blocking
versions of some syscalls (blocking the current thread instead of the
whole process). Ideally this would mean that existing
(i.e. non-yielding) Lisp code would not be affected, and network code
could be run in a background thread.
The greatest obstacle to this seems to be shallow binding - you'd have
to unwind one thread's stack and rewind another's when switching
threads. Maybe there's an easier way that I don't see...
Magnus
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-08 18:01 ` Magnus Henoch
@ 2005-06-08 19:52 ` Nic Ferrier
2005-06-08 20:23 ` jhd
2005-06-08 21:43 ` Magnus Henoch
2005-06-09 14:40 ` Richard Stallman
1 sibling, 2 replies; 37+ messages in thread
From: Nic Ferrier @ 2005-06-08 19:52 UTC (permalink / raw)
Cc: emacs-devel
Magnus Henoch <mange@freemail.hu> writes:
> I've been thinking about using GNU pth to implement threads in Emacs.
> GNU pth only does cooperative threading, and has special non-blocking
> versions of some syscalls (blocking the current thread instead of the
> whole process). Ideally this would mean that existing
> (i.e. non-yielding) Lisp code would not be affected, and network code
> could be run in a background thread.
>
> The greatest obstacle to this seems to be shallow binding - you'd have
> to unwind one thread's stack and rewind another's when switching
> threads. Maybe there's an easier way that I don't see...
I don't see why this subject keeps coming up.
We don't need threads in elisp. Just more asynchronous network
implementations.
Anyway, async code is so much more fun to write than threaded
code. Threads are for beginners.
Nic Ferrier
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-08 19:52 ` Nic Ferrier
@ 2005-06-08 20:23 ` jhd
2005-06-08 20:47 ` Nic Ferrier
2005-06-08 21:43 ` Magnus Henoch
1 sibling, 1 reply; 37+ messages in thread
From: jhd @ 2005-06-08 20:23 UTC (permalink / raw)
Cc: Magnus Henoch, emacs-devel
>> The greatest obstacle to this seems to be shallow binding - you'd
>> have
>> to unwind one thread's stack and rewind another's when switching
>> threads. Maybe there's an easier way that I don't see...
>>
>
> I don't see why this subject keeps coming up.
>
> We don't need threads in elisp. Just more asynchronous network
> implementations.
>
> Anyway, async code is so much more fun to write than threaded
> code. Threads are for beginners.
Async network code won't take advantage of multiple CPU:s. Threads do.
Jan D.
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-08 20:23 ` jhd
@ 2005-06-08 20:47 ` Nic Ferrier
2005-06-08 22:50 ` Stefan Monnier
0 siblings, 1 reply; 37+ messages in thread
From: Nic Ferrier @ 2005-06-08 20:47 UTC (permalink / raw)
Cc: Magnus Henoch, emacs-devel
jhd <jan.h.d@swipnet.se> writes:
>>> The greatest obstacle to this seems to be shallow binding - you'd
>>> have
>>> to unwind one thread's stack and rewind another's when switching
>>> threads. Maybe there's an easier way that I don't see...
>>>
>>
>> I don't see why this subject keeps coming up.
>>
>> We don't need threads in elisp. Just more asynchronous network
>> implementations.
>>
>> Anyway, async code is so much more fun to write than threaded
>> code. Threads are for beginners.
>
> Async network code won't take advantage of multiple CPU:s. Threads
> do.
Pth, for example, won't take advantage of multiple CPUs.
I think elisp is always going to need a huge amount of blocking to use
OS threads because of the nature of dynamic scope.
Emacs does already get an advantage from multiple CPUs because it uses
co-processes a lot. Co-processes are much less burdensome on
multi-core architectures. The best way to handle co-processes is with
async IO.
Nic
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-08 19:52 ` Nic Ferrier
2005-06-08 20:23 ` jhd
@ 2005-06-08 21:43 ` Magnus Henoch
2005-06-08 22:26 ` Nic Ferrier
2005-06-09 14:41 ` Richard Stallman
1 sibling, 2 replies; 37+ messages in thread
From: Magnus Henoch @ 2005-06-08 21:43 UTC (permalink / raw)
Nic Ferrier <nferrier@tapsellferrier.co.uk> writes:
> We don't need threads in elisp. Just more asynchronous network
> implementations.
Good point.
What is the best way to send a large amount of data to a network
connection in the background? You could send a chunk at a time with
process-send-string and then recurse with run-with-idle-timer, but it
seems that this will either block the UI or cause unnecessarily slow
transfer unless the chunk size and the delay are right.
> Anyway, async code is so much more fun to write than threaded
> code. Threads are for beginners.
Can you elaborate? I don't see how
(defun foo-1 ()
(send-request-with-callback 'foo-2))
(defun foo-2 (response)
(do-something response))
is more fun to write than:
(defun foo ()
(let ((response (send-request-and-get-response)))
(do-something response)))
Magnus
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-08 21:43 ` Magnus Henoch
@ 2005-06-08 22:26 ` Nic Ferrier
2005-06-09 14:41 ` Richard Stallman
1 sibling, 0 replies; 37+ messages in thread
From: Nic Ferrier @ 2005-06-08 22:26 UTC (permalink / raw)
Cc: emacs-devel
Magnus Henoch <mange@freemail.hu> writes:
> Nic Ferrier <nferrier@tapsellferrier.co.uk> writes:
>
>> We don't need threads in elisp. Just more asynchronous network
>> implementations.
>
> Good point.
>
> What is the best way to send a large amount of data to a network
> connection in the background? You could send a chunk at a time with
> process-send-string and then recurse with run-with-idle-timer, but it
> seems that this will either block the UI or cause unnecessarily slow
> transfer unless the chunk size and the delay are right.
How about putting the data in a buffer and using:
process-send-region
In respect of sending lots of data, the same problem applies when
using either threads or async. Consider the example of the text of the
play The Tempest to a network process.
The user can kill the buffer, alter the buffer, delete bits from the
buffer, all while the transfer is going on. So the only way to achieve
this is to lock the buffer first.
>> Anyway, async code is so much more fun to write than threaded
>> code. Threads are for beginners.
>
> Can you elaborate? I don't see how
>
> (defun foo-1 ()
> (send-request-with-callback 'foo-2))
>
> (defun foo-2 (response)
> (do-something response))
>
> is more fun to write than:
>
> (defun foo ()
> (let ((response (send-request-and-get-response)))
> (do-something response)))
I was trying to be amusing. Asynchronous code is much harder to write
than threaded code, hence threaded code is for beginners.
Nic
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-08 20:47 ` Nic Ferrier
@ 2005-06-08 22:50 ` Stefan Monnier
0 siblings, 0 replies; 37+ messages in thread
From: Stefan Monnier @ 2005-06-08 22:50 UTC (permalink / raw)
Cc: jhd, Magnus Henoch, emacs-devel
> I think elisp is always going to need a huge amount of blocking to use
> OS threads because of the nature of dynamic scope.
I expect that making cooperative threads work (with context switches only at
those places where we currently allow running things like timers and process
filters), is currently doable.
I.e. it will probably introduce some incompatibilities, but it shouldn't be
hugely difficult to get a proof of concept working well enough for
"normal" use.
Once we get there, it may be easier to see what the next step should be.
Stefan
PS: Making progress on lexical scoping will also make it easier to
move forward.
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
@ 2005-06-09 0:29 Steven Wu
0 siblings, 0 replies; 37+ messages in thread
From: Steven Wu @ 2005-06-09 0:29 UTC (permalink / raw)
It will be better if someone pick up guile-emacs works. Guile is
multithreaded and async IO. To bad that work is not going fast enough.
steve
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-08 18:01 ` Magnus Henoch
2005-06-08 19:52 ` Nic Ferrier
@ 2005-06-09 14:40 ` Richard Stallman
2005-06-10 19:09 ` Ted Zlatanov
1 sibling, 1 reply; 37+ messages in thread
From: Richard Stallman @ 2005-06-09 14:40 UTC (permalink / raw)
Cc: emacs-devel
The greatest obstacle to this seems to be shallow binding - you'd have
to unwind one thread's stack and rewind another's when switching
threads. Maybe there's an easier way that I don't see...
That is how the Lisp Machine worked. It is not an unreasonable idea.
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-08 21:43 ` Magnus Henoch
2005-06-08 22:26 ` Nic Ferrier
@ 2005-06-09 14:41 ` Richard Stallman
1 sibling, 0 replies; 37+ messages in thread
From: Richard Stallman @ 2005-06-09 14:41 UTC (permalink / raw)
Cc: emacs-devel
> We don't need threads in elisp. Just more asynchronous network
> implementations.
Multiple threads are the only way to make the support for
multiple terminals in a single Emacs process really work right.
I am not sure to what extent full support for multiple terminals is
really useful in this day and age. But that is something to think
about.
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-09 14:40 ` Richard Stallman
@ 2005-06-10 19:09 ` Ted Zlatanov
2005-06-11 3:48 ` Masatake YAMATO
2005-06-11 12:18 ` Richard Stallman
0 siblings, 2 replies; 37+ messages in thread
From: Ted Zlatanov @ 2005-06-10 19:09 UTC (permalink / raw)
On Thu, 09 Jun 2005, rms@gnu.org wrote:
> The greatest obstacle to this seems to be shallow binding - you'd have
> to unwind one thread's stack and rewind another's when switching
> threads. Maybe there's an easier way that I don't see...
>
> That is how the Lisp Machine worked. It is not an unreasonable idea.
I think an alternate solution is to have no shared variables between
threads once they are forked, and communicate through standard IPC
(pipes, semaphores, etc.). This would preserve backwards
compatibility and speed, while using more memory and making the
programmers' job harder (but the lower number of bugs may be worth
it).
Ted
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-10 19:09 ` Ted Zlatanov
@ 2005-06-11 3:48 ` Masatake YAMATO
2005-06-11 12:18 ` Richard Stallman
1 sibling, 0 replies; 37+ messages in thread
From: Masatake YAMATO @ 2005-06-11 3:48 UTC (permalink / raw)
Cc: emacs-devel
> I think an alternate solution is to have no shared variables between
> threads once they are forked, and communicate through standard IPC
> (pipes, semaphores, etc.).
Interesting.
I have never imaged this idea.
How do you think linda instead of the standard IPC.
http://heather.cs.ucdavis.edu/~matloff/Linda/NotesLinda.NM.html
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-10 19:09 ` Ted Zlatanov
2005-06-11 3:48 ` Masatake YAMATO
@ 2005-06-11 12:18 ` Richard Stallman
2005-06-15 15:59 ` Ted Zlatanov
1 sibling, 1 reply; 37+ messages in thread
From: Richard Stallman @ 2005-06-11 12:18 UTC (permalink / raw)
Cc: emacs-devel
I think an alternate solution is to have no shared variables between
threads once they are forked, and communicate through standard IPC
(pipes, semaphores, etc.).
This is not possible with shallow binding. All Lisp programs
use the same set of symbols, and each symbol has a value.
Many symbols' values have important standard meanings.
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-11 12:18 ` Richard Stallman
@ 2005-06-15 15:59 ` Ted Zlatanov
2005-06-15 23:26 ` Miles Bader
0 siblings, 1 reply; 37+ messages in thread
From: Ted Zlatanov @ 2005-06-15 15:59 UTC (permalink / raw)
On Sat, 11 Jun 2005, rms@gnu.org wrote:
> I think an alternate solution is to have no shared variables between
> threads once they are forked, and communicate through standard IPC
> (pipes, semaphores, etc.).
>
> This is not possible with shallow binding. All Lisp programs
> use the same set of symbols, and each symbol has a value.
> Many symbols' values have important standard meanings.
I'm not sure I understand the problem. Do you mean that if a user
changes variable A in thread 1, he expects thread 2 to also notice the
change for certain global variables? That's easy to do, if you
consider that such global variables are few and far between compared
to local per-thread variables. defvar and similar could just be
allowed to make a variable :global, and then any change in any thread
would be propagated to the other threads by the VM.
I realize this is extra work for the programmers. Multithreading is
never free, but the advantages are significant as well.
Ted
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-15 15:59 ` Ted Zlatanov
@ 2005-06-15 23:26 ` Miles Bader
2005-06-16 16:25 ` Ted Zlatanov
0 siblings, 1 reply; 37+ messages in thread
From: Miles Bader @ 2005-06-15 23:26 UTC (permalink / raw)
Cc: emacs-devel
On 6/16/05, Ted Zlatanov <tzz@lifelogs.com> wrote:
> I'm not sure I understand the problem. Do you mean that if a user
> changes variable A in thread 1, he expects thread 2 to also notice the
> change for certain global variables? That's easy to do, if you
> consider that such global variables are few and far between compared
> to local per-thread variables.
This is not really true for typical elisp programs -- global variables
(especially buffer-local global variables) are used extremely often,
and in almost every case must be "truly global" (visible in all
threads).
However, if a global variable is let-bound, the let-binding should of
course be thread-local.
My personal feeling is that it may be easiest to simply move to a
deep-binding system for elisp (and ideally use lexical-binding for
local variables), but such a change may be a lot of work given the
myriad special varieties of variable bindings (buffer-local etc).
-Miles
--
Do not taunt Happy Fun Ball.
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-15 23:26 ` Miles Bader
@ 2005-06-16 16:25 ` Ted Zlatanov
2005-06-17 0:56 ` Miles Bader
0 siblings, 1 reply; 37+ messages in thread
From: Ted Zlatanov @ 2005-06-16 16:25 UTC (permalink / raw)
On Thu, 16 Jun 2005, snogglethorpe@gmail.com wrote:
On 6/16/05, Ted Zlatanov <tzz@lifelogs.com> wrote:
>> I'm not sure I understand the problem. Do you mean that if a user
>> changes variable A in thread 1, he expects thread 2 to also notice the
>> change for certain global variables? That's easy to do, if you
>> consider that such global variables are few and far between compared
>> to local per-thread variables.
>
> This is not really true for typical elisp programs -- global variables
> (especially buffer-local global variables) are used extremely often,
> and in almost every case must be "truly global" (visible in all
> threads).
At the time of the fork, the thread will pick up all globals. I was
talking about important globals that are modified after the fork. At
least my experience has been that after you initialize Emacs, it's
rare to modify globally important variables unless you are
specifically customizing Emacs.
By far, I'm not as experienced with Emacs internals and packages as
you and many others on this list, so please excuse any dumb
suggestions :)
> However, if a global variable is let-bound, the let-binding should
> of course be thread-local.
Yes. Perhaps let-bindings will end up being the only thread-local
bindings and the VM will pay the stack penalties RMS mentioned. I
just hope it doesn't have to be that way.
> My personal feeling is that it may be easiest to simply move to a
> deep-binding system for elisp (and ideally use lexical-binding for
> local variables), but such a change may be a lot of work given the
> myriad special varieties of variable bindings (buffer-local etc).
Whatever the path, I'm just excited that others have picked up on the
multithreading Emacs idea, and I'll be glad to contribute what I can
to the effort.
Ted
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-16 16:25 ` Ted Zlatanov
@ 2005-06-17 0:56 ` Miles Bader
2005-06-17 14:09 ` Ted Zlatanov
0 siblings, 1 reply; 37+ messages in thread
From: Miles Bader @ 2005-06-17 0:56 UTC (permalink / raw)
Cc: emacs-devel
On 6/17/05, Ted Zlatanov <tzz@lifelogs.com> wrote:
> > This is not really true for typical elisp programs -- global variables
> > (especially buffer-local global variables) are used extremely often,
> > and in almost every case must be "truly global" (visible in all
> > threads).
>
> At the time of the fork, the thread will pick up all globals. I was
> talking about important globals that are modified after the fork. At
> least my experience has been that after you initialize Emacs, it's
> rare to modify globally important variables unless you are
> specifically customizing Emacs.
No, it's _extremely_ common.
A huge amount of the actively maintained state in Emacs is stored in
global variables (often buffer-local of course, but still "global" as
far as threads are concerned).
-Miles
--
Do not taunt Happy Fun Ball.
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-17 0:56 ` Miles Bader
@ 2005-06-17 14:09 ` Ted Zlatanov
2005-06-17 18:47 ` Richard Stallman
2005-06-20 2:11 ` Miles Bader
0 siblings, 2 replies; 37+ messages in thread
From: Ted Zlatanov @ 2005-06-17 14:09 UTC (permalink / raw)
On Fri, 17 Jun 2005, snogglethorpe@gmail.com wrote:
> A huge amount of the actively maintained state in Emacs is stored in
> global variables (often buffer-local of course, but still "global"
> as far as threads are concerned).
Thank you for the clarification.
I'm thinking of ways to avoid the stack penalties the other proposals
involve. Could we allow only secondary threads with thread-local
variables and forked copies of globals? Then, to modify the main
thread's version of a global variable a special protocol must be
followed (through the VM). Threads wouldn't be able to access
existing buffers and buffer-local variables without going through the
VM protocol, either (but they can create their own buffers, which will
be isolated within the thread). The ideal thread would be a pure
function (if I remember my definitions right, a pure function f(x)
depends only on x).
This will make threads more of a utility than a true built-in, and
threaded code would be written especially for that purpose. Existing
code would continue to run without changes - this will save us
rewriting a huge amount of code.
Is this feasible? Would this kind of limited threading be useful?
Ted
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-17 14:09 ` Ted Zlatanov
@ 2005-06-17 18:47 ` Richard Stallman
2005-06-20 18:04 ` Ted Zlatanov
2005-06-20 2:11 ` Miles Bader
1 sibling, 1 reply; 37+ messages in thread
From: Richard Stallman @ 2005-06-17 18:47 UTC (permalink / raw)
Cc: emacs-devel
I'm thinking of ways to avoid the stack penalties the other proposals
involve. Could we allow only secondary threads with thread-local
variables and forked copies of globals?
"Forked copies of globals" would mean copies of the values of
thousands of Lisp symbols. And how would the Lisp interpreter know
whether and where to look for them? It does not seem practical.
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-17 14:09 ` Ted Zlatanov
2005-06-17 18:47 ` Richard Stallman
@ 2005-06-20 2:11 ` Miles Bader
2005-06-20 10:28 ` Nic Ferrier
2005-06-20 17:52 ` Ted Zlatanov
1 sibling, 2 replies; 37+ messages in thread
From: Miles Bader @ 2005-06-20 2:11 UTC (permalink / raw)
Cc: emacs-devel
On 6/17/05, Ted Zlatanov <tzz@lifelogs.com> wrote:
> This will make threads more of a utility than a true built-in, and
> threaded code would be written especially for that purpose.
Do you know of any applications that require this? For many purposes,
using timers etc. seems to work fairly well already.
The main reason I can see for wanting threading is to allow users to
continue using Emacs in one window while waiting for another window
that's doing something (e.g. Gnus updating over a dialup). However
that level of functionality is hard to implement.
-Miles
--
Do not taunt Happy Fun Ball.
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-20 2:11 ` Miles Bader
@ 2005-06-20 10:28 ` Nic Ferrier
2005-06-20 11:19 ` Lennart Borgman
2005-06-20 11:48 ` David Kastrup
2005-06-20 17:52 ` Ted Zlatanov
1 sibling, 2 replies; 37+ messages in thread
From: Nic Ferrier @ 2005-06-20 10:28 UTC (permalink / raw)
Cc: Ted Zlatanov, emacs-devel, miles
Miles Bader <snogglethorpe@gmail.com> writes:
> On 6/17/05, Ted Zlatanov <tzz@lifelogs.com> wrote:
>> This will make threads more of a utility than a true built-in, and
>> threaded code would be written especially for that purpose.
>
> Do you know of any applications that require this? For many purposes,
> using timers etc. seems to work fairly well already.
>
> The main reason I can see for wanting threading is to allow users to
> continue using Emacs in one window while waiting for another window
> that's doing something (e.g. Gnus updating over a dialup). However
> that level of functionality is hard to implement.
I think that's the problem isn't it? Analysis of what benefit Emacs
could get from threads.
We don't need threads for improving GNUs - we just need better async
protocol implementations. They will come, slowly, but surely.
I think threads would be most useful for things like fontification and
parsing (eg: in xml buffers).
When you think about these applications a bolt on thread model looks
less attractive.
Nic
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-20 10:28 ` Nic Ferrier
@ 2005-06-20 11:19 ` Lennart Borgman
2005-06-20 11:48 ` David Kastrup
1 sibling, 0 replies; 37+ messages in thread
From: Lennart Borgman @ 2005-06-20 11:19 UTC (permalink / raw)
Cc: miles, Ted Zlatanov, snogglethorpe, emacs-devel
Nic Ferrier wrote:
>I think threads would be most useful for things like fontification and
>parsing (eg: in xml buffers).
>
>
nxml-mode works pretty well for parsing and fontifying xml.
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-20 10:28 ` Nic Ferrier
2005-06-20 11:19 ` Lennart Borgman
@ 2005-06-20 11:48 ` David Kastrup
2005-06-20 12:07 ` Nic Ferrier
1 sibling, 1 reply; 37+ messages in thread
From: David Kastrup @ 2005-06-20 11:48 UTC (permalink / raw)
Cc: miles, Ted Zlatanov, snogglethorpe, emacs-devel
Nic Ferrier <nferrier@tapsellferrier.co.uk> writes:
> Miles Bader <snogglethorpe@gmail.com> writes:
>
>> On 6/17/05, Ted Zlatanov <tzz@lifelogs.com> wrote:
>>> This will make threads more of a utility than a true built-in, and
>>> threaded code would be written especially for that purpose.
>>
>> Do you know of any applications that require this? For many purposes,
>> using timers etc. seems to work fairly well already.
>>
>> The main reason I can see for wanting threading is to allow users to
>> continue using Emacs in one window while waiting for another window
>> that's doing something (e.g. Gnus updating over a dialup). However
>> that level of functionality is hard to implement.
>
> I think that's the problem isn't it? Analysis of what benefit Emacs
> could get from threads.
>
> We don't need threads for improving GNUs - we just need better async
> protocol implementations. They will come, slowly, but surely.
The problem is that you always have a number of tasks that need to get
tackled one after the other. And this can always done without threads
or even subroutine calls, by storing all relevant details of the
state, like counters, current point etc and so on and then jumping to
central dispatch points.
It is all the same for a computer. It isn't for a human. Subroutines
and stacks are currently in use quite heftily for maintaining the
inner state of some nested tasks pretty much in every programming
language.
Now if you have a data _stream_ passing between two different
computing tasks, then each of those tasks has its own inner states to
keep track of, its own local variables, its wn control structure and
so on.
Yes, you _can_ always explicitly hard-code all of that, but that means
that you'll do so only when avoiding it would be more painful than the
alternatives.
When I was younger, I programmed a terminal emulator for use in a BIOS
of mine, and several other stuff in that area.
Now you have escape sequences for cursor positioning that go something
like ESC [ row, column; or so (don't remember the details). So what
states can the console output code be in? Well, it can be after the
escape sequence, it can be in the middle of assembling of the row, it
can be in the middle of assembling the column, stuff like that. And
there are dozens of sequences like that.
In the end, I programmed this more or less like
basicloop:
cp 1ah
jp nz,noesc
call getchar
cp '[
jp nz,nocursor (actually, this was rather done via a jump table)
call getnumber
cp ',
jnz badsequence
push hl
call getnumber
pop de
cp ';
jnz badsequence
set hl=something*hl + something*de
ld (cursor),hl
jp basicloop
badsequence:
sound bell
jp basicloop
getnumber:
ld hl,0
push hl
call getchar
pop hl
ret if a is not in '0..9
set hl=10*hl + a-'0
jmp getnumber
Stuff like that. And then the tricky thing could all be done in
"getchar". And getchar just switched from a local stack for the
terminal emulator to the stack of the caller, and returned.
And the console output simply switched from the stack of the caller to
the stack of the terminal emulator, and returned.
The whole "inner state" was maintained all inside of a separate
stack. This was multithreading in connection with synchronous task
switching, if you so wanted, even though in the 80s those buzzwords
were not all around.
And the purpose was to concentrate the "hard" stuff in very few
locations, and facilitate "natural" programming everywhere else.
And that's what multithreading is about: making conceptually easy
tasks easy to code. Not merely making them possible to code: you can
always hardcode the inner state maintained by the combination of a
stack and the program counter.
But it is hard, error-prone work.
--
David Kastrup, Kriemhildstr. 15, 44793 Bochum
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-20 11:48 ` David Kastrup
@ 2005-06-20 12:07 ` Nic Ferrier
0 siblings, 0 replies; 37+ messages in thread
From: Nic Ferrier @ 2005-06-20 12:07 UTC (permalink / raw)
Cc: miles, Ted Zlatanov, snogglethorpe, emacs-devel
David Kastrup <dak@gnu.org> writes:
> And that's what multithreading is about: making conceptually easy
> tasks easy to code. Not merely making them possible to code: you can
> always hardcode the inner state maintained by the combination of a
> stack and the program counter.
>
> But it is hard, error-prone work.
I wouldn't say writing async network protocol implementations is as
hard as you suggest. It's hard, but not that hard.
But it would be too hard to try and write async fontification code and
that's where threads would really help.
Given that, a simple, *very* partitioned thread model would not be
much use. It would make network programming *slightly* simpler, but
would not allow us to make font-lock quicker, or xml parse in the
background.
Nic
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-20 2:11 ` Miles Bader
2005-06-20 10:28 ` Nic Ferrier
@ 2005-06-20 17:52 ` Ted Zlatanov
1 sibling, 0 replies; 37+ messages in thread
From: Ted Zlatanov @ 2005-06-20 17:52 UTC (permalink / raw)
On Mon, 20 Jun 2005, snogglethorpe@gmail.com wrote:
> Do you know of any applications that require this? For many purposes,
> using timers etc. seems to work fairly well already.
Gnus summary threading and spam processing, for example, could benefit
greatly from multi-threading. It does not require it.
Ted
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-17 18:47 ` Richard Stallman
@ 2005-06-20 18:04 ` Ted Zlatanov
2005-06-21 15:13 ` Richard M. Stallman
0 siblings, 1 reply; 37+ messages in thread
From: Ted Zlatanov @ 2005-06-20 18:04 UTC (permalink / raw)
On Fri, 17 Jun 2005, rms@gnu.org wrote:
> I'm thinking of ways to avoid the stack penalties the other proposals
> involve. Could we allow only secondary threads with thread-local
> variables and forked copies of globals?
>
> "Forked copies of globals" would mean copies of the values of
> thousands of Lisp symbols. And how would the Lisp interpreter know
> whether and where to look for them? It does not seem practical.
Don't make copies of the globals then, unless they are modified.
If the secondary thread modifies a global, make the copy then (Copy On
Write).
If the primary thread modifies a global, trigger a copy for every
thread of the OLD value (null op if no threads exist).
The interpreter would just have to keep a hashtable of hashtables;
primary key is the secondary thread ID and the secondary key is the
global symbol. When a thread modifies a global, look in the HoH; if
the symbol is not in there you create an entry. To get a symbol value
in a thread, you do two hashtable lookups; in the primary thread
there's no lookups.
There should be a way that a thread can send data back to the main
thread on request (the main thread asks for the data).
Ted
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-20 18:04 ` Ted Zlatanov
@ 2005-06-21 15:13 ` Richard M. Stallman
2005-06-21 18:36 ` Nic Ferrier
0 siblings, 1 reply; 37+ messages in thread
From: Richard M. Stallman @ 2005-06-21 15:13 UTC (permalink / raw)
Cc: emacs-devel
If the secondary thread modifies a global, make the copy then (Copy On
Write).
This would be difficult to implement, considering that a symbol's value
is normally kept in its value cell.
The interpreter would just have to keep a hashtable of hashtables;
primary key is the secondary thread ID and the secondary key is the
global symbol. When a thread modifies a global, look in the HoH; if
the symbol is not in there you create an entry.
That would make the usual case much slower.
I prefer the idea of swapping bindings on thread switches.
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-21 15:13 ` Richard M. Stallman
@ 2005-06-21 18:36 ` Nic Ferrier
2005-06-22 3:40 ` Richard M. Stallman
0 siblings, 1 reply; 37+ messages in thread
From: Nic Ferrier @ 2005-06-21 18:36 UTC (permalink / raw)
Cc: Ted Zlatanov, emacs-devel
"Richard M. Stallman" <rms@gnu.org> writes:
> That would make the usual case much slower.
> I prefer the idea of swapping bindings on thread switches.
As I understand it such an implementation would not take advantage of
the new hardware that supports multi-threading, eg: multi-core x86
processors.
Nic
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Threads in emacs implementation
2005-06-21 18:36 ` Nic Ferrier
@ 2005-06-22 3:40 ` Richard M. Stallman
0 siblings, 0 replies; 37+ messages in thread
From: Richard M. Stallman @ 2005-06-22 3:40 UTC (permalink / raw)
Cc: tzz, emacs-devel
As I understand it such an implementation would not take advantage of
the new hardware that supports multi-threading, eg: multi-core x86
processors.
I am not sure that case is important, or that it would outweigh
the slowness of all variable accesses.
I don't think that Emacs will often have multiple threads actually
trying to run. If multiple users are typing on one Emacs, only
occasionally will they both run nontrivial commands at once.
^ permalink raw reply [flat|nested] 37+ messages in thread
end of thread, other threads:[~2005-06-22 3:40 UTC | newest]
Thread overview: 37+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-06-08 8:24 Threads in emacs implementation tomas
-- strict thread matches above, loose matches on Subject: below --
2005-06-09 0:29 Steven Wu
2005-06-07 2:22 Denis Bueno
2005-06-07 2:52 ` Miles Bader
2005-06-07 2:59 ` Denis Bueno
2005-06-07 4:26 ` Miles Bader
2005-06-07 5:16 ` Ken Raeburn
2005-06-07 10:37 ` Nic Ferrier
2005-06-08 12:02 ` Richard Stallman
2005-06-08 18:01 ` Magnus Henoch
2005-06-08 19:52 ` Nic Ferrier
2005-06-08 20:23 ` jhd
2005-06-08 20:47 ` Nic Ferrier
2005-06-08 22:50 ` Stefan Monnier
2005-06-08 21:43 ` Magnus Henoch
2005-06-08 22:26 ` Nic Ferrier
2005-06-09 14:41 ` Richard Stallman
2005-06-09 14:40 ` Richard Stallman
2005-06-10 19:09 ` Ted Zlatanov
2005-06-11 3:48 ` Masatake YAMATO
2005-06-11 12:18 ` Richard Stallman
2005-06-15 15:59 ` Ted Zlatanov
2005-06-15 23:26 ` Miles Bader
2005-06-16 16:25 ` Ted Zlatanov
2005-06-17 0:56 ` Miles Bader
2005-06-17 14:09 ` Ted Zlatanov
2005-06-17 18:47 ` Richard Stallman
2005-06-20 18:04 ` Ted Zlatanov
2005-06-21 15:13 ` Richard M. Stallman
2005-06-21 18:36 ` Nic Ferrier
2005-06-22 3:40 ` Richard M. Stallman
2005-06-20 2:11 ` Miles Bader
2005-06-20 10:28 ` Nic Ferrier
2005-06-20 11:19 ` Lennart Borgman
2005-06-20 11:48 ` David Kastrup
2005-06-20 12:07 ` Nic Ferrier
2005-06-20 17:52 ` Ted Zlatanov
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).