emacs-devel
[Top][All Lists]
Advanced

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

Re: Multithreading, again and again


From: Tom Tromey
Subject: Re: Multithreading, again and again
Date: Wed, 19 Oct 2011 09:14:11 -0600
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.90 (gnu/linux)

>>>>> "Dmitry" == Dmitry Antipov <address@hidden> writes:

Sorry about the delay in my reply to this.
I was away for quite a while.

Dmitry> 0. What we have, and where we go.
Dmitry>    What's the status of git://gitorious.org/emacs-mt/emacs-mt.git and
Dmitry>    http://bzr.savannah.gnu.org/r/emacs/concurrency? Whether there are
Dmitry>    plans for further development?

I consider both of those obsolete.

The concurrency branch in bzr has some problems.  I think parts of it
are not a good direction to go.

I have a different branch here ("concurrency-2") but I haven't pushed it
yet.  I could do that if there is interest.  It is not yet at par with
the old concurrency branch; in fact in ways it is very far behind (I
didn't tackle bindings yet -- the code changed on the trunk and I'm not
sure the old code was correct anyhow).

I don't have much free time for hacking, so it is hard to make progress.
I could use some help!  I'd be happy to push my branch and write up what
I think should be done.

Dmitry> 1. To thread or not to thread?

I think so, but I don't know if there is consensus around it.

Dmitry> 2. Hide them all!
Dmitry>    Should the threads be visible (may be created and managed)
Dmitry>    from Lisp, or they can just do some work orthogonal to it? If
Dmitry>    latter, which tasks may be implicitly threaded? Redisplay
Dmitry>    (one thread per frame)? Buffer/socket I/O? GC? Is it feasible
Dmitry>    to implement full implicit concurrency? For the rough
Dmitry>    example, with the Lisp engine as the pool of threads, where
Dmitry>    (eval FORM) just queues the FORM and then ask the pool to
Dmitry>    find a free thread and evaluate it?

I think that generally threads should be explicit, just because that is
simpler to understand.  I find it hard to picture how some implicit
scheme could work.

There are two situations where I think some kind of hidden thread would
be useful.

One is DNS lookup.  This should be threaded internally, so that DNS
delays don't hang Emacs.  This could actually be done today without
requiring exposing threads to Emacs.

The other is the multiple keyboard case.  I think it should be possible
to have each 'emacsclient -t' run in a separate thread.

People have talked about making redisplay run in its own thread, but I
don't know anything about redisplay and so I haven't looked at it.

You could make the GC run in a separate thread, which would be pretty
cool, but I think it would be hard.

Dmitry> 3. Too big, too global.
Dmitry>    How to split/share/synchronize huge global state between threads?
Dmitry>    What should be thread-local? (I feel (current-buffer) should be
Dmitry>    global and max-lisp-eval-depth should be thread-local, but I suspect
Dmitry>    that there are much more controversial cases). Is it reasonable to
Dmitry>    have become-thread-local-on-write globals?

I think current-buffer has to be per-thread.  Anything else means that a
context switch can randomly change buffers.

A good chunk of the work is making decisions like this.  On the branch I
have moved a number of global variables into the 'struct thread' object.

I would rather not introduce new ways of doing variable bindings.  This
area is already very complicated, complicated enough that it is the main
problem in finishing this branch.  Instead, threads can use 'let' to
introduce a thread-local binding.

Dmitry> 4. Say "thread"!
Dmitry>    What should be done in C to implement thread management in Lisp?
Dmitry>    I feel basically
[...]

My plan was to follow the Bordeaux threads API, more or less.
This is something from CL.

Dmitry> 5. You and I.
Dmitry>    What synchronization primitives should be implemented? Atomic 
variables?
Dmitry>    Mutexes/semaphores? Barriers? Higher-level not-so-primitives like
Dmitry>    thread pools or multithreaded queues? Should some basic operations,
Dmitry>    like setq, be always atomic? Is it reasonable/feasible/useful to have
Dmitry>    special form like (with-atomic BODY...), where all BODY forms are 
evaluated
Dmitry>    atomically with respect to all other threads?

I was planning to just do some primitives (mutex and condition
variables) and then let people write whatever else in Lisp.

Dmitry> 6. Under the cover.
Dmitry>    What other low-level changes are required for thread support?
Dmitry>    Basic structure of Lisp objects? Multiple stacks scanning for GC?
Dmitry>    Per-thread heaps for small objects?

Lisp objects don't need to change.  I already made the GC work.  You
could do a per-thread heap if you wanted, though I don't think there is
a benefit yet, since (1) Emacs Lisp isn't exactly high performance,  and
(2) the initial threading model is "mostly cooperative", with context
switch occurring only at I/O and (thread-yield) calls.

Tom



reply via email to

[Prev in Thread] Current Thread [Next in Thread]