unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* 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; 51+ 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] 51+ messages in thread

* Re: Threads in emacs implementation
  2005-06-07  2:22 Threads in emacs implementation 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; 51+ 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] 51+ 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; 51+ 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] 51+ 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; 51+ 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] 51+ messages in thread

* Re: Threads in emacs implementation
  2005-06-07  2:22 Threads in emacs implementation 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; 51+ 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] 51+ 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; 51+ 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] 51+ messages in thread

* Re: Threads in emacs implementation
@ 2005-06-08  8:24 tomas
  0 siblings, 0 replies; 51+ 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] 51+ 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; 51+ 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] 51+ messages in thread

* Re: Threads in emacs implementation
  2005-06-07  2:22 Threads in emacs implementation 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; 51+ 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] 51+ 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; 51+ 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] 51+ 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; 51+ 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] 51+ 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; 51+ 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] 51+ 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
                         ` (2 more replies)
  1 sibling, 3 replies; 51+ 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] 51+ messages in thread

* Re: Threads in emacs implementation
  2005-06-08 21:43     ` Magnus Henoch
@ 2005-06-08 22:26       ` Nic Ferrier
  2005-06-08 22:34       ` hidden buffers for async (was Re: Threads in emacs implementation) Nic Ferrier
  2005-06-09 14:41       ` Threads in emacs implementation Richard Stallman
  2 siblings, 0 replies; 51+ 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] 51+ messages in thread

* hidden buffers for async (was Re: Threads in emacs implementation)
  2005-06-08 21:43     ` Magnus Henoch
  2005-06-08 22:26       ` Nic Ferrier
@ 2005-06-08 22:34       ` Nic Ferrier
  2005-06-08 23:36         ` Miles Bader
  2005-06-10  0:13         ` Richard Stallman
  2005-06-09 14:41       ` Threads in emacs implementation Richard Stallman
  2 siblings, 2 replies; 51+ messages in thread
From: Nic Ferrier @ 2005-06-08 22:34 UTC (permalink / raw)


Related to the discussion about threads is the issue of making
asycnhronous network programming in emacs easier.

I wrote an article on how I tried and failed (for now) to write a good
async IMAP library in elisp:

  http://www.tapsellferrier.co.uk/nics-articles/imapua-failure.html


One of the things that stopped me achieving this was that I felt I
couldn't create a lot of buffers specifically for storing bits of
in progress IMAP data.

Something that would help a great deal is if one could create a buffer
that was hidden, ie: it did not ordinarily appear in the buffer list
and was not returned by a call to:

    (get-buffer buffername)

maybe because the buffer wouldn't have a name.


Anybody else think this is a good idea? 

Is it doable?


I know this is all a bit blue sky and we're supposed to be focused on
the next release... my apologies, but I think this is not a large
change and I do believe it would help with async a lot.


Nic

^ permalink raw reply	[flat|nested] 51+ 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; 51+ 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] 51+ messages in thread

* Re: hidden buffers for async (was Re: Threads in emacs implementation)
  2005-06-08 22:34       ` hidden buffers for async (was Re: Threads in emacs implementation) Nic Ferrier
@ 2005-06-08 23:36         ` Miles Bader
  2005-06-10  0:13         ` Richard Stallman
  1 sibling, 0 replies; 51+ messages in thread
From: Miles Bader @ 2005-06-08 23:36 UTC (permalink / raw)
  Cc: emacs-devel

On 6/9/05, Nic Ferrier <nferrier@tapsellferrier.co.uk> wrote:
> Something that would help a great deal is if one could create a buffer
> that was hidden, ie: it did not ordinarily appear in the buffer list
> and was not returned by a call to:
> 
>     (get-buffer buffername)

Why?

The goal of not annoying users is served well enough by the
leading-space convention, and there's ample support for creating
unique buffers; why do you need a truly anonymous buffer?

-Miles
-- 
Do not taunt Happy Fun Ball.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: Threads in emacs implementation
@ 2005-06-09  0:29 Steven Wu
  0 siblings, 0 replies; 51+ 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] 51+ 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; 51+ 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] 51+ messages in thread

* Re: Threads in emacs implementation
  2005-06-08 21:43     ` Magnus Henoch
  2005-06-08 22:26       ` Nic Ferrier
  2005-06-08 22:34       ` hidden buffers for async (was Re: Threads in emacs implementation) Nic Ferrier
@ 2005-06-09 14:41       ` Richard Stallman
  2 siblings, 0 replies; 51+ 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] 51+ messages in thread

* Re: hidden buffers for async (was Re: Threads in emacs implementation)
  2005-06-08 22:34       ` hidden buffers for async (was Re: Threads in emacs implementation) Nic Ferrier
  2005-06-08 23:36         ` Miles Bader
@ 2005-06-10  0:13         ` Richard Stallman
  2005-06-10  1:15           ` hidden buffers for async Nic Ferrier
  1 sibling, 1 reply; 51+ messages in thread
From: Richard Stallman @ 2005-06-10  0:13 UTC (permalink / raw)
  Cc: emacs-devel

    Something that would help a great deal is if one could create a buffer
    that was hidden, ie: it did not ordinarily appear in the buffer list
    and was not returned by a call to:

	(get-buffer buffername)

Why do you think this is necessary?
I don't see what problem this would solve.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: hidden buffers for async
  2005-06-10  0:13         ` Richard Stallman
@ 2005-06-10  1:15           ` Nic Ferrier
  2005-06-10  1:32             ` Luc Teirlinck
  2005-06-10 22:37             ` Richard Stallman
  0 siblings, 2 replies; 51+ messages in thread
From: Nic Ferrier @ 2005-06-10  1:15 UTC (permalink / raw)
  Cc: emacs-devel

")
Message-ID: <87psuv8116.fsf@kanga.tapsellferrier.co.uk>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii

Richard Stallman <rms@gnu.org> writes:

>     Something that would help a great deal is if one could create a buffer
>     that was hidden, ie: it did not ordinarily appear in the buffer list
>     and was not returned by a call to:
>
> 	(get-buffer buffername)
>
> Why do you think this is necessary?
> I don't see what problem this would solve.

Buffers are more convieniant (and more efficient) than strings for
large amounts of data. But buffers are very visible to the user and
that makes them less attractive for storing purely temporary or
transient data.


A concrete example. IMAP does file transfers with variable sized
chunks. It states the chunk size and then sends that many bytes of the
file. But you don't recieve all the bytes at once in an elisp async
reciever. 

I wanted to use a buffer to collect the data from the chunks while the
file transfer was still going on.

But IMAP can be asked to download lots of files at once and will be
chunking them all. So I wanted to have lots of chunk buffers, one for
each file transfer. When the files are downloaded they can be put
straight into the correct mode for displaying the file.

So there might be 10 or 20 (or 1000) buffers all recieving chunks of
files from IMAP. But these are purely temporary objects, until IMAP
sends a "file downloaded" status message the buffers are just data
stores. So I wanted to hide them from the user.

I think there are a lot of protocols where this happens. HTTP is
similar and so is NNTP.



Nic

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: hidden buffers for async
  2005-06-10  1:15           ` hidden buffers for async Nic Ferrier
@ 2005-06-10  1:32             ` Luc Teirlinck
  2005-06-10  1:59               ` Nic Ferrier
  2005-06-10 22:37             ` Richard Stallman
  1 sibling, 1 reply; 51+ messages in thread
From: Luc Teirlinck @ 2005-06-10  1:32 UTC (permalink / raw)
  Cc: rms, emacs-devel

Nic Ferrier wrote:

   So I wanted to hide them from the user.

Which does not answer a question already asked by Miles: why is
starting their names with a space not good enough?

Sincerely,

Luc.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: hidden buffers for async
  2005-06-10  1:32             ` Luc Teirlinck
@ 2005-06-10  1:59               ` Nic Ferrier
  0 siblings, 0 replies; 51+ messages in thread
From: Nic Ferrier @ 2005-06-10  1:59 UTC (permalink / raw)
  Cc: rms, emacs-devel

Luc Teirlinck <teirllm@dms.auburn.edu> writes:

> Nic Ferrier wrote:
>
>    So I wanted to hide them from the user.
>
> Which does not answer a question already asked by Miles: why is
> starting their names with a space not good enough?

Sorry, didn't see that from miles. Not sure why.

Fantastic! I never knew about that. That's perfect for what I
want. Thank you.


Nic

^ permalink raw reply	[flat|nested] 51+ 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; 51+ 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] 51+ messages in thread

* Re: hidden buffers for async
  2005-06-10  1:15           ` hidden buffers for async Nic Ferrier
  2005-06-10  1:32             ` Luc Teirlinck
@ 2005-06-10 22:37             ` Richard Stallman
  2005-06-11 20:26               ` Nic Ferrier
  1 sibling, 1 reply; 51+ messages in thread
From: Richard Stallman @ 2005-06-10 22:37 UTC (permalink / raw)
  Cc: emacs-devel

    But IMAP can be asked to download lots of files at once and will be
    chunking them all. So I wanted to have lots of chunk buffers, one for
    each file transfer. When the files are downloaded they can be put
    straight into the correct mode for displaying the file.

    So there might be 10 or 20 (or 1000) buffers all recieving chunks of
    files from IMAP.

Creating that many buffers might cause various sorts of overload
for Emacs.  Can't you use one buffer for all the information,
and sort it out at the end?

^ permalink raw reply	[flat|nested] 51+ 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; 51+ 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] 51+ 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; 51+ 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] 51+ messages in thread

* Re: hidden buffers for async
  2005-06-10 22:37             ` Richard Stallman
@ 2005-06-11 20:26               ` Nic Ferrier
  2005-06-11 21:05                 ` Henrik Enberg
                                   ` (2 more replies)
  0 siblings, 3 replies; 51+ messages in thread
From: Nic Ferrier @ 2005-06-11 20:26 UTC (permalink / raw)
  Cc: emacs-devel

Richard Stallman <rms@gnu.org> writes:

>     But IMAP can be asked to download lots of files at once and will be
>     chunking them all. So I wanted to have lots of chunk buffers, one for
>     each file transfer. When the files are downloaded they can be put
>     straight into the correct mode for displaying the file.
>
>     So there might be 10 or 20 (or 1000) buffers all recieving chunks of
>     files from IMAP.
>
> Creating that many buffers might cause various sorts of overload
> for Emacs.  Can't you use one buffer for all the information,
> and sort it out at the end?

The number of buffers would be 1:1 with the number of files being
downloaded. Aggregating the data is the problem I was trying to avoid.
Because the downloads all finish at different times it makes sorting
the data difficult.

I agree that downloading a lot of files will be silly. Perhaps I will
set up a pool of 20 or so buffers for downloads and block or error
when the pool is exhausted.

Would that be a good idea?


Nic

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: hidden buffers for async
  2005-06-11 20:26               ` Nic Ferrier
@ 2005-06-11 21:05                 ` Henrik Enberg
  2005-06-12 10:30                 ` Richard Stallman
  2005-06-12 17:18                 ` Stefan Monnier
  2 siblings, 0 replies; 51+ messages in thread
From: Henrik Enberg @ 2005-06-11 21:05 UTC (permalink / raw)
  Cc: rms, emacs-devel

Nic Ferrier <nferrier@tapsellferrier.co.uk> writes:

> Richard Stallman <rms@gnu.org> writes:

[...]

>> Creating that many buffers might cause various sorts of overload
>> for Emacs.  Can't you use one buffer for all the information,
>> and sort it out at the end?

[...]

> I agree that downloading a lot of files will be silly. Perhaps I will
> set up a pool of 20 or so buffers for downloads and block or error
> when the pool is exhausted.
>
> Would that be a good idea?

If it's feasible, yes.  Even if using 1000 buffers wasn't a problem
memory-wise.  I much prefer programs that doesn't saturate my net
connection completely.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: hidden buffers for async
  2005-06-11 20:26               ` Nic Ferrier
  2005-06-11 21:05                 ` Henrik Enberg
@ 2005-06-12 10:30                 ` Richard Stallman
  2005-06-12 19:48                   ` Nic Ferrier
  2005-06-12 17:18                 ` Stefan Monnier
  2 siblings, 1 reply; 51+ messages in thread
From: Richard Stallman @ 2005-06-12 10:30 UTC (permalink / raw)
  Cc: emacs-devel

    The number of buffers would be 1:1 with the number of files being
    downloaded. Aggregating the data is the problem I was trying to avoid.
    Because the downloads all finish at different times it makes sorting
    the data difficult.

When you say "sorting the data", do you mean that literally?  What I
would think of doing is simply looking thru the data assembling the
contents that add up to one file, and saving it out when it is
complete.

    I agree that downloading a lot of files will be silly. Perhaps I will
    set up a pool of 20 or so buffers for downloads and block or error
    when the pool is exhausted.

That should work, if it is ok to do only 20 transfers in parallel.
It should block, not error, when all are in use.

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: hidden buffers for async
  2005-06-11 20:26               ` Nic Ferrier
  2005-06-11 21:05                 ` Henrik Enberg
  2005-06-12 10:30                 ` Richard Stallman
@ 2005-06-12 17:18                 ` Stefan Monnier
  2005-06-13  6:03                   ` Juri Linkov
  2 siblings, 1 reply; 51+ messages in thread
From: Stefan Monnier @ 2005-06-12 17:18 UTC (permalink / raw)
  Cc: rms, emacs-devel

> I agree that downloading a lot of files will be silly. Perhaps I will
> set up a pool of 20 or so buffers for downloads and block or error
> when the pool is exhausted.

My guess is that the possible performance hit you'd get by using 100 or
1000 buffers would still be insignificant.


        Stefan "whose Emacs routinely has 100 buffers"

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: hidden buffers for async
  2005-06-12 10:30                 ` Richard Stallman
@ 2005-06-12 19:48                   ` Nic Ferrier
  2005-06-13 15:03                     ` Richard Stallman
  0 siblings, 1 reply; 51+ messages in thread
From: Nic Ferrier @ 2005-06-12 19:48 UTC (permalink / raw)
  Cc: emacs-devel

Richard Stallman <rms@gnu.org> writes:

>     The number of buffers would be 1:1 with the number of files being
>     downloaded. Aggregating the data is the problem I was trying to avoid.
>     Because the downloads all finish at different times it makes sorting
>     the data difficult.
>
> When you say "sorting the data", do you mean that literally?  

No.


> What I would think of doing is simply looking thru the data
> assembling the contents that add up to one file, and saving it out
> when it is complete.

The advantage of multiple buffers is that the downloaded files can be
viewed straight away, with no further copying. Some files could even
be viewed *while* they were still downloading. A bit like a browser
does with image files.



>     I agree that downloading a lot of files will be silly. Perhaps I will
>     set up a pool of 20 or so buffers for downloads and block or error
>     when the pool is exhausted.
>
> That should work, if it is ok to do only 20 transfers in parallel.
> It should block, not error, when all are in use.

Why?

If this code were an elisp library I think I would expect it to
error... and then user code could choose to block on repeated calls
with a time delay.

Wouldn't that be better?


(Sorry, this is an important question to me, since I am going to
implement this code).


Nic

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: hidden buffers for async
  2005-06-12 17:18                 ` Stefan Monnier
@ 2005-06-13  6:03                   ` Juri Linkov
  0 siblings, 0 replies; 51+ messages in thread
From: Juri Linkov @ 2005-06-13  6:03 UTC (permalink / raw)
  Cc: rms, nferrier, emacs-devel

>> I agree that downloading a lot of files will be silly. Perhaps I will
>> set up a pool of 20 or so buffers for downloads and block or error
>> when the pool is exhausted.
>
> My guess is that the possible performance hit you'd get by using 100 or
> 1000 buffers would still be insignificant.
>
>         Stefan "whose Emacs routinely has 100 buffers"

M-: (length (buffer-list)) RET
322

I rarely close visited files and use desktop.el.  This way I give Emacs
pretty good stress-testing.  With so many buffers some Emacs packages
(Dired, Info) suffer from the noticeable slowdown.  However, I can't
definitely attribute this to the number of buffers, because in
`emacs -Q -D' after (dotimes (i 1000) (generate-new-buffer "buffer"))
there is no slowdown.

-- 
Juri Linkov
http://www.jurta.org/emacs/

^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: hidden buffers for async
  2005-06-12 19:48                   ` Nic Ferrier
@ 2005-06-13 15:03                     ` Richard Stallman
  0 siblings, 0 replies; 51+ messages in thread
From: Richard Stallman @ 2005-06-13 15:03 UTC (permalink / raw)
  Cc: emacs-devel

    The advantage of multiple buffers is that the downloaded files can be
    viewed straight away, with no further copying.

I am not sure what you're really trying to do here.
Is your goal to ultimately have each message in a separate buffer?
Or is the goal to write them into files on disk?

    > That should work, if it is ok to do only 20 transfers in parallel.
    > It should block, not error, when all are in use.

    Why?

I suspect we are miscommunicating, talking about different levels
of code.  However, I can't see why it could be useful for any
level whatsoever to get an error just because someone asks it to
download more than 20 messages.

^ permalink raw reply	[flat|nested] 51+ 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; 51+ 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] 51+ 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; 51+ 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] 51+ 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; 51+ 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] 51+ 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; 51+ 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] 51+ 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; 51+ 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] 51+ 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; 51+ 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] 51+ 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; 51+ 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] 51+ 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; 51+ 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] 51+ 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; 51+ 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] 51+ 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; 51+ 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] 51+ 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; 51+ 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] 51+ 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; 51+ 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] 51+ 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; 51+ 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] 51+ 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; 51+ 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] 51+ 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; 51+ 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] 51+ 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; 51+ 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] 51+ messages in thread

end of thread, other threads:[~2005-06-22  3:40 UTC | newest]

Thread overview: 51+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-06-07  2:22 Threads in emacs implementation 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-08 22:34       ` hidden buffers for async (was Re: Threads in emacs implementation) Nic Ferrier
2005-06-08 23:36         ` Miles Bader
2005-06-10  0:13         ` Richard Stallman
2005-06-10  1:15           ` hidden buffers for async Nic Ferrier
2005-06-10  1:32             ` Luc Teirlinck
2005-06-10  1:59               ` Nic Ferrier
2005-06-10 22:37             ` Richard Stallman
2005-06-11 20:26               ` Nic Ferrier
2005-06-11 21:05                 ` Henrik Enberg
2005-06-12 10:30                 ` Richard Stallman
2005-06-12 19:48                   ` Nic Ferrier
2005-06-13 15:03                     ` Richard Stallman
2005-06-12 17:18                 ` Stefan Monnier
2005-06-13  6:03                   ` Juri Linkov
2005-06-09 14:41       ` Threads in emacs implementation 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
  -- strict thread matches above, loose matches on Subject: below --
2005-06-08  8:24 tomas
2005-06-09  0:29 Steven Wu

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).