From: David Steuber "The Interloper
Subject: CMUCL on the sly (and threads)
Date: 
Message-ID: <3630e63c.270653639@news.newsguy.com>
For purely selfish reasons, I installed the SunOS Sparc 18b version of
CMUCL on to one of the machines at the company where I work.  I didn't
ask anyone if I could do it.  I just did it.  It's always easier to
apologize than to get permission :-).

The selfish reason is mainly to give myself another physical location
where I can learn the Lisp.  Also, in the future, I can discover
portability issues of large Lisp programs by going from x86 to Sparc,
or the other way.

I've alluded to the desire for CORBA and threading support in lisp in
a different thread.  At the risk of creating a race hazard, I will
elaborate my motives for wanting these things here.

Imagine a WWW site that delivers stock information, account
information, and accepts trade orders.  www.suretrade.com is a perfect
example (mainly because that site is hosted by the company I work for
and contains some code that I wrote buried deep in its guts).
Suretrade.com also executes many thousands of trades per day and peaks
at the multi-thousand level per hour.  That is just trades.  There are
also account look-ups, quotes, news, and many other services.  Some
are farmed out to other sites.  Many are done locally.

There is a lot of iron behind the website.  Part of that iron is
wasted in my opinion because of the software used for generating
pages.  The software was chosen because it is very flexible.  It is
far more flexible than Active Server Pages from Microsoft.
Unfortunately, it is at least a full order of magnitude slower than
ASP.  So now other pages, like www.moneynet.com (also by the company,
but none of my code is there, different department) are served up by
NT servers using ASP.

I've probably said enough to get me fired, but what the hell, I'll go
on.  BTW, I do recommend both sites if you are interested in the U.S.
stock markets.

I see that Lisp has the potential to reduce the amount of iron
necessary to deliver HTML.  I haven't looked at CL-HTTP yet.  Someone
else in this group mentioned high license fees, so I don't think I
will.  I want to work with free tools in my spare time so that I don't
have to justify anything to the company.  I think that CMUCL is going
to remain my Lisp of choice by the mere fact that all the source is
available and it is public domain.  I don't have to worry about
proprietary technology from a company that might disappear.  I am
already on that road.

So what does the Lisp have to do to deliver dynamically generated HTML
documents at a high rate?  Well, it has to be multithreaded for one
thing.  At any given instant in time, there can be upwards of 60
simultaneous connections being serviced.  The other thing the Lisp
needs to be able to do is talk to CORBA (the Orbix ORB).  Talking
directly to Oracle would be nice, but the new architecture that is
being built is CORBA based and database access is being provided by
CORBA services to present a uniform data model.  So, the absence of
either CORBA or threading is an absolute show stopper.  Another
important point is that like with ASP, the fact that the page
generation code may be running in many different threads at once must
be completely transparent to the code and the person who writes it.

What I end up with is the need for a Lisp module that the web server
can talk to (NSAPI or sockets) that has some configured number of
connections to the ORB daemon for hitting the back end, and the
ability to service perhaps as many as several hundred page requests
concurrently.  Speed matters.

An alternative is to go with Java 1.2.  I can deal with the networking
and threading issues quite easily in Java.  Also, 1.2 includes a CORBA
package from omg.org.  Page generation code would be considerably more
awkward in Java than in Lisp though.

I think I have a litmus test for Lisp.  When you look at Emacs and
AutoCad, you see the core of the product is really written in C.  That
is also true for CMUCL, but that doesn't mean a pure Lisp system can't
be built with it.  The question is, can a system like the one I
described above be built with it?

As far as threading is concerned, I think that this is an important
enough topic that some sort of standard should be provided.  Threading
is inherently system dependant, so it seems that the best solution
would be to have a standard package that abstracts the system
dependent nature of threading.  Java achieves this by virtue of using
a virtual machine.  JIT compilers mean that native code can also
abstract threading.  The facilities offered by Java are on the simple
side.  However, I think that there is sufficient functionality there
to be useful.

Here is an off the cuff proposal for a set of functionality that would
be in a thread package.  I will use pseudo-Lisp because I am not
fluent in the real thing yet.

;;; Need to be able to start a thread
(begin-thread &entry-function (args)
	"Begins a new thread and calls entry-function, passing it an
optional list of arguments.  Function returns immediately.  The return
value is a locked mutex object if successful, else nil.  When
entry-function returns, mutex becomes unlocked")

;;; Need to be able to create a mutex object some other way
(create-mutex
	"returns a mutex object in an unlocked state")

;;; Need to be able to lock the mutex object
(lock (m [to])
	"locks the mutex.  If the mutex is already locked, then this
function blocks for up to the optional time out period (in
milliseconds) until the mutex is unlocked.  Returns the mutex if
successful, else nil.")

;;; Need to be able to unlock the mutex object
(unlock (m)
	"unlocks the mutex.  Returns the unlocked mutex if successful,
else nil if you didn't own the mutex")

The above list is incomplete.  Mechanisms for suspending or killing
threads from other threads may be useful.  Also, a means to create a
named mutex that can be queried by any other thread in the system (to
see if an event occurred) would also be useful.  Don't forget thread
priority.  The Win32 API has some nice thread support.  The consing
that can occur in threads affects the gc.  If thread support is to be
enabled, then consing and gc need to be made thread safe.  A function
should be provided to tell the lisp runtime that threading is enabled
so that consing and gc can be done safely.  Calling this function to
enable threading should be required before using any other thread
functions.

I don't see how servers or distributed processing can be achieved
without the notion of threads.  Certainly not efficiently.  The
normal, "I'm only human" disclaimer applies.  Perhaps there is a
portable solution that I don't know about or using a slew of processes
is not so expensive as I imagine it to be.  I think it is though.

One last thing before I sign of.  If I haven't already put you to
sleep.

While testing the Sparc installation of CMUCL, I wrote a normal
recursive form of the factorial function, specifically:

(defun fact (n)
	(if (< n 2)
		1
		(* n fact(- n 1))))

(fact 1000) returned a nice large number.
(fact 2000) triggered a segment fault, and lisp dumped core.  I
thought this couldn't happen?

--
David Steuber (ver 1.31.2a)
http://www.david-steuber.com
To reply by e-mail, replace trashcan with david.

So I have this chicken, see?  And it hatched from this egg, see?  But
the egg wasn't laid by a chicken.  It was cross-laid by a turkey.

From: Rainer Joswig
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <joswig-2310980848210001@194.163.195.67>
In article <··················@news.newsguy.com>,
········@david-steuber.com wrote:


> necessary to deliver HTML.  I haven't looked at CL-HTTP yet.  Someone
> else in this group mentioned high license fees, so I don't think I
> will

Yep, the license fees are ******extremely****** high!

Basically you can CL-HTTP use wherever you want (academic, personal,
commercial),
you have to tell that you are using CL-HTTP, you have to submit
improvements and extensions of CL-HTTP (but not your application!) to the
community, ...

But otherwise it does *****not**** ******cost**** *****anything*****

We have here an extremely valuable piece of software (ask what you pay
for a commercial version of such a software). Some Lisp wizards
have dumped a lot of effort into this and they just don't
want to see CL-HTTP having the fate of some other systems
(Garnet wird garnet mehr entwickelt. CLIM????).
CL-HTTP actually is in production use on some platforms
and companies have using it.
CL-HTTP is a service to the Lisp community. Contributions
are welcome.

Better people read the license, see what the restrictions are,
and contact the developer if she/he has a problem with that.

-- 
http://www.lavielle.com/~joswig
From: David Steuber "The Interloper
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <36365d91.8728961@news.newsguy.com>
On Fri, 23 Oct 1998 08:48:07 +0200, ······@lavielle.com (Rainer
Joswig) claimed or asked:

% In article <··················@news.newsguy.com>,
% ········@david-steuber.com wrote:
% 
% 
% > necessary to deliver HTML.  I haven't looked at CL-HTTP yet.  Someone
% > else in this group mentioned high license fees, so I don't think I
% > will
% 
% Yep, the license fees are ******extremely****** high!
% 
% Basically you can CL-HTTP use wherever you want (academic, personal,
% commercial),
% you have to tell that you are using CL-HTTP, you have to submit
% improvements and extensions of CL-HTTP (but not your application!) to the
% community, ...
% 
% But otherwise it does *****not**** ******cost**** *****anything*****

Are you suggesting that I read licenses for myself rather than
listening to someone who says the license fee is just too high? :-)

OK, now I'm just going to have to look at that package.  I just hope I
can understand it.

Everything I say is wrong.

--
David Steuber (ver 1.31.2a)
http://www.david-steuber.com
To reply by e-mail, replace trashcan with david.

"Ignore reality there's nothing you can do about it..."
-- Natalie Imbruglia "Don't you think?"
From: Rainer Joswig
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <joswig-2310980849490001@194.163.195.67>
In article <··················@news.newsguy.com>,
········@david-steuber.com wrote:

> (defun fact (n)
>         (if (< n 2)
>                 1
>                 (* n fact(- n 1))))
> 
> (fact 1000) returned a nice large number.
> (fact 2000) triggered a segment fault, and lisp dumped core.  I
> thought this couldn't happen?

Send a bug report to the maintainers.

-- 
http://www.lavielle.com/~joswig
From: David Steuber "The Interloper
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <36375e4b.8914538@news.newsguy.com>
On Fri, 23 Oct 1998 08:49:49 +0200, ······@lavielle.com (Rainer
Joswig) claimed or asked:

% Send a bug report to the maintainers.

I fetched this version from CMU.  From reading through some of the
stuff, I'm not sure there are any maintainers for this code.  I'll get
the version from cons.org and check it before I bother them.

I also want to install the source in case I can get some trace
information.  Hmmm.  I wonder if I have to run dbg on the core file
for that?

--
David Steuber (ver 1.31.2a)
http://www.david-steuber.com
To reply by e-mail, replace trashcan with david.

"Ignore reality there's nothing you can do about it..."
-- Natalie Imbruglia "Don't you think?"
From: Peter Van Eynde
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <slrn730ifv.sg4.pvaneynd@mail.inthan.be>
On Fri, 23 Oct 1998 03:47:47 GMT, 
  David Steuber "The Interloper" <········@david-steuber.com> wrote:
>I think I have a litmus test for Lisp.  When you look at Emacs and
>AutoCad, you see the core of the product is really written in C.  That
>is also true for CMUCL, but that doesn't mean a pure Lisp system can't

It isn't. There a is C core, but it only has 2 functions:
 1 Load the binary lisp image into memory and jump to it
 2 Provide a few low-level functions, like memory allocation, parts
   of the GC and signal handling functions.

It's just used for convenience.

>Here is an off the cuff proposal for a set of functionality that would
>be in a thread package.  I will use pseudo-Lisp because I am not
>fluent in the real thing yet.

Look at www.cons.org for a document about threading, and to CLX and cl-http for 
portable interfaces...

>The above list is incomplete.  Mechanisms for suspending or killing
>threads from other threads may be useful.  Also, a means to create a

Suspending is not possible with conventional Posix-threads :-(.

>While testing the Sparc installation of CMUCL, I wrote a normal
>recursive form of the factorial function, specifically:
>
>(defun fact (n)
>	(if (< n 2)
>		1
>		(* n fact(- n 1))))

In Common Lisp:

(defun fact (n)
 (if (< n 2)
     1
     (* n (fact (1- n)))))

It works on x86:

Script started on Fri Oct 23 10:54:37 1998
QOTD:
	"I used to get high on life but lately I've built up a resistance."
pvaneynd:~$ lisp
CMU Common Lisp 18a+ release x86-linux 2.4.6 13 October 1998 cvs, running on \
mail
Send bug reports and questions to your local CMU CL maintainer, 
or to ········@debian.org
or to ··········@cons.org. (prefered)

type (help) for help, (quit) to exit, and (demo) to see the demos

Loaded subsystems:
    Python 1.0, target Intel x86
    CLOS based on PCL version:  September 16 92 PCL (f)
* (defun fact (n)
 (if (< n 2)
     1
     (* n (fact (1- n)))))

FACT
* (defun time-fact (n) (time (progn (fact n) t)))

TIME-FACT
* (time-fact 1000)
Warning:  TIME form in a non-null environment, forced to interpret.
Compiling entire form will produce more accurate times.

Evaluation took:
  0.06 seconds of real time
  0.06 seconds of user run time
  0.0 seconds of system run time
  7 page faults and
  666680 bytes consed.
T
* (time-fact 2000)
Warning:  TIME form in a non-null environment, forced to interpret.
Compiling entire form will produce more accurate times.
[GC threshold exceeded with 2,000,064 bytes in use.  Commencing GC.]
[GC completed with 253,240 bytes retained and 1,746,824 bytes freed.]
[GC will next occur when at least 2,253,240 bytes are in use.]

Evaluation took:
  0.19 seconds of real time
  0.17 seconds of user run time
  0.01 seconds of system run time
  [Run times include 0.06 seconds GC run time]
  484 page faults and
  2504648 bytes consed.
T
* (compile 'fact)
Compiling LAMBDA (N): 
Compiling Top-Level Form: 

FACT
NIL
NIL
* (compile 'time-fact)
Compiling LAMBDA (N): 
Compiling Top-Level Form: 

TIME-FACT
NIL
NIL
* (time-fact 2000)

[GC threshold exceeded with 2,253,776 bytes in use.  Commencing GC.]
[GC completed with 264,392 bytes retained and 1,989,384 bytes freed.]
[GC will next occur when at least 2,264,392 bytes are in use.]

Evaluation took:
  0.09 seconds of real time
  0.05 seconds of user run time
  0.02 seconds of system run time
  [Run times include 0.05 seconds GC run time]
  0 page faults and
  2222328 bytes consed.
T

* (quit)
pvaneynd:~$ exit
exit

Script done on Fri Oct 23 10:56:27 1998

Groetjes, Peter

--
It's logic Jim, but not as we know it.  ········@debian.org, ········@inthan.be
Look in keyservers for PGP key.
From: Duane Rettig
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <4n26ngrak.fsf@beta.franz.com>
········@mail.inthan.be (Peter Van Eynde) writes:
> On Fri, 23 Oct 1998 03:47:47 GMT, 
>   David Steuber "The Interloper" <········@david-steuber.com> wrote:

> >While testing the Sparc installation of CMUCL, I wrote a normal
> >recursive form of the factorial function, specifically:
> >
> >(defun fact (n)
> >	(if (< n 2)
> >		1
> >		(* n fact(- n 1))))

I assume that the missing parens was just a transcripting typo.

> In Common Lisp:
> 
> (defun fact (n)
>  (if (< n 2)
>      1
>      (* n (fact (1- n)))))
> 
> It works on x86:

Sorry to be picky, but in at least one respect you are not running the
same test as the original poster (see below) ...

> * (defun fact (n)
>  (if (< n 2)
>      1
>      (* n (fact (1- n)))))
> 
> FACT

Here is the problem:

> * (defun time-fact (n) (time (progn (fact n) t)))

Note that your test is not printing the result.  It may be surprising,
but most of the work in printing factorials is not in the calculating
of the factorials themselves, but in converting the bignum result to
decimal; it takes many, many divisions, and tends to blow lisps out
due to the extreme consing (unless it is accounted for).

To prove this to yourself in almost any lisp, try timing
(- (fact 1000) (fact 1000)) vs (fact 1000); the results should
be startling enough to use a stopwatch.

It may be that the original poster's problem was not with stack
overflow, but with some other limit.  Or, if it is a stack
overflow, it could be due to the resource limits set for the
userid (run the limit command in a csh).

I assume from the script that you did not compile fact.  This
(the interpreted version) is a good worst-case test.  For the
obligatory advertisement :-), Allegro CL can get through
almost 7000 interpreted recursions before it gives a continuable
stack overflow signal:

Allegro CL Enterprise Edition 5.0 [Linux/X86] (8/29/98 10:36)
Copyright (C) 1985-1998, Franz Inc., Berkeley, CA, USA.  All Rights Reserved.
;; Optimization settings: safety 1, space 1, speed 1, debug 2.
;; For a complete description of all compiler switches given the
;; current optimization settings evaluate (EXPLAIN-COMPILER-SETTINGS).
USER(1): (defun fact (n)
 (if (< n 2)
     1
     (* n (fact (1- n)))))
FACT
USER(2): (fact 10000)
Error: Stack overflow (signal 1000)
  [condition type: SYNCHRONOUS-OPERATING-SYSTEM-SIGNAL]

Restart actions (select using :continue):
 0: continue computation
 1: Return to Top Level (an "abort" restart)
[1c] USER(3): :zo
Evaluation stack:

   (CERROR "continue computation" SYNCHRONOUS-OPERATING-SYSTEM-SIGNAL
           ...)
 ->(SYS::..CONTEXT-SAVING-RUNTIME-OPERATION)
   (FACT 3281)
   (FACT 3282)
   (FACT 3283)
   (FACT 3284)
   (FACT 3285)
   (FACT 3286)
   (FACT 3287)

... more older frames ...
[1c] USER(4): 

Admittedly, there was a bug that didn't let me continue from that
overflow in linux (the bug doesn't exist in the NT or sparc versions),
but I've fixed it in my sources, and now continuing allows the rest
of the computation.  Trying the same thing on a sparc also gives a
stack overflow, and continuing results in completion of the
calculation (although much more slowly, due to sparc's special
slowness with recursion due to register windows).

When compiled, (fact 10000) easily finishes and outputs pages of numbers.

-- 
Duane Rettig          Franz Inc.            http://www.franz.com/ (www)
1995 University Ave Suite 275  Berkeley, CA 94704
Phone: (510) 548-3600; FAX: (510) 548-8253   ·····@Franz.COM (internet)
From: David Steuber "The Interloper
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <36386150.9688000@news.newsguy.com>
On Fri, 23 Oct 1998 11:18:55 +0200, ········@mail.inthan.be (Peter Van
Eynde) claimed or asked:

% On Fri, 23 Oct 1998 03:47:47 GMT, 
%   David Steuber "The Interloper" <········@david-steuber.com> wrote:
% >I think I have a litmus test for Lisp.  When you look at Emacs and
% >AutoCad, you see the core of the product is really written in C.  That
% >is also true for CMUCL, but that doesn't mean a pure Lisp system can't
% 
% It isn't. There a is C core, but it only has 2 functions:
%  1 Load the binary lisp image into memory and jump to it
%  2 Provide a few low-level functions, like memory allocation, parts
%    of the GC and signal handling functions.
% 
% It's just used for convenience.

Next, you will tell me that LILO isn't the core of Linux :-)

% >Here is an off the cuff proposal for a set of functionality that would
% >be in a thread package.  I will use pseudo-Lisp because I am not
% >fluent in the real thing yet.
% 
% Look at www.cons.org for a document about threading, and to CLX and cl-http for 
% portable interfaces...

So much is there.  Could you please be more specific?
 
% Suspending is not possible with conventional Posix-threads :-(.

Can Lisp (I know, see cons.org) do it's own threading, or is the OS
required?  Java manages it somehow.  Or maybe it doesn't.
 
% >While testing the Sparc installation of CMUCL, I wrote a normal
% >recursive form of the factorial function, specifically:
% >
% >(defun fact (n)
% >	(if (< n 2)
% >		1
% >		(* n fact(- n 1))))
% 
% In Common Lisp:
% 
% (defun fact (n)
%  (if (< n 2)
%      1
%      (* n (fact (1- n)))))
% 
% It works on x86:

It worked on my Linux machine at home too.  I didn't bother timing it.
The recursive version didn't blow the stack until I threw in 100000.
It tossed me into the debugger or something equally graceful.  It was
just the Sparc version that blew up on me.

--
David Steuber (ver 1.31.2a)
http://www.david-steuber.com
To reply by e-mail, replace trashcan with david.

"Ignore reality there's nothing you can do about it..."
-- Natalie Imbruglia "Don't you think?"
From: Barry Margolin
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <MvBY1.62$VI.1167623@burlma1-snr1.gtei.net>
In article <················@news.newsguy.com>,
David Steuber "The Interloper" <········@david-steuber.com> wrote:
>Can Lisp (I know, see cons.org) do it's own threading, or is the OS
>required?  Java manages it somehow.  Or maybe it doesn't.

Most commercial Unix Lisps have had multi-threading for years, long before
the OSes had them.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
From: Martin Cracauer
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <70uuvp$gdq$1@counter.bik-gmbh.de>
········@david-steuber.com (David Steuber "The Interloper") writes:

>% >Here is an off the cuff proposal for a set of functionality that would
>% >be in a thread package.  I will use pseudo-Lisp because I am not
>% >fluent in the real thing yet.
>% 
>% Look at www.cons.org for a document about threading, and to CLX and cl-http for 
>% portable interfaces...

>So much is there.  Could you please be more specific?

http://www.cons.org/cracauer/lisp-threads.html is an overview of
existing thread interfaces for Common Lisp. CMUCL 18b on x86
implements something similar to the portable interface in the CLIM
specification.

>% Suspending is not possible with conventional Posix-threads :-(.

>Can Lisp (I know, see cons.org) do it's own threading, or is the OS
>required?  Java manages it somehow.  Or maybe it doesn't.

All Common Lisp systems in wider distribution implement threads
internally, no Unix or Win32 kernel support is used, OS-supplied
libraries for C interfaces aren't used as a base.

The original Java VM from Sun on Unix did implement threading in its
own code as well. It's threading core is written in C, but no OS
functionality is used. Later, versions to use Solaris threads had been
developed.

Martin
From: Tim Bradshaw
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <ey3k91nle6f.fsf@todday.aiai.ed.ac.uk>
* Martin Cracauer wrote:

> All Common Lisp systems in wider distribution implement threads
> internally, no Unix or Win32 kernel support is used, OS-supplied
> libraries for C interfaces aren't used as a base.

This is interesting, because it's probably becoming a problem for CLs.
One of the main benefits of a multithreaded system (at least from my
point of view) is that you can make good use of the cheap (relatively)
multiprocessors that are now available.  I suspect fairly strongly
that in order to do this you really need to build on top of the OS
threading, because only the OS can really know enough to arrange for
threads to be properly distributed over CPUs.

It would be interesting to know how hard it is to do a Lisp
multithreading system on top of whatever threads the OS provides
(Posix, for Unixoid systems?), and how multiprocessor-friendly the
various existing lisp multithreading APIs are as well.

I've only looked into this for one implementation -- Unix Allegro --
and it certainly does seem to be a problem there, although Franz are
aware of it and are clearly intending to fix it at some point.  I
think it may already be fixed for Win32 Allegro (v5).

This could well be a case where `getting there first' turns out to be
a burden in the end.

--tim
From: David Gadbois
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <zw0kiuh4ftvp.fsf@lagavulin.cyc.com>
Tim Bradshaw <···@aiai.ed.ac.uk> writes:
> It would be interesting to know how hard it is to do a Lisp
> multithreading system on top of whatever threads the OS provides
> (Posix, for Unixoid systems?),

I recently added multi-threading support for a Lisp system and spent
some time evaluating the POSIX pthreads interface before coming to the
conclusion that it is not useful for implementing the usual Lisp style
threads.

There are two critical facilities that pthreads does not have.  One is
the ability to do safely and efficiently a global synchronization of
all the threads.  This is necessary because there are a number of
infrequent situations where you want to modify some global state but
don't want to put a mutex around it for frequent non-synchronized
accesses. [1]

The other missing facility is that there is no way to "pin" a thread
to a particular processor.  This is necessary because there is often
some state, such as memory pools, that could otherwise avoid most
synchronization overhead, and it obviates the need for expensive
mechanisms for dealing with weak memory consistency models. [2]

Also, there were a couple of non-technical issues.  One is that the
current fielded implementations of pthreads are far (far!) from being
standardized.  There are enough differences that basing Lisp threads
on pthreads would essentially require separate code bases for each
implementation, and, in some case, separate bases for different
versions of each implementation.  A testing and maintenance nightmare.
Second, one must take Win32 into account these days, and it has
different enough models that simple functional and macro abstraction
to a pthreads-like model won't cut it.

I ended up doing the usual coroutine-based stack-group switcher.
Support for actual multiprocessing would be nice, but the engineering
and maintenance effort looks truly enormous.  It will be interesting
to see if Franz has some tricks that reduce the problem to something
tractable.

> and how multiprocessor-friendly the various existing lisp
> multithreading APIs are as well.

They are not.  At all.  There are a couple of problems.  One is that
the usual Lisp style threads have a view of a globally accessible and
consistent object store.  This view just does not mesh with current
APIs (and hardware!) that really want you to minimize global state.
Another problem is the usual quality-of-implementation expectation
that, unless you try really hard, user code cannot damage the system
as a whole; every error is recoverable.

Note that I am not knocking the usual Lisp style threads.  They are
marvelously easy and safe to program to.  Try programming to pthreads
or the Win32 model du jour sometime to see the difference.  It is just
that current hardware, OS's, APIs, are not a good fit.  Can't wait for
this wheel of reincarnation to turn.

There are other multiprocessing models for Lisp that may be more
current-trend friendly.  Check out Connection Machine Lisp and Kelly
Murray's stuff.  There may be something to learn from how Java does
things:  its model is not so far off, and lots of good people are
working on how to implement it well.  Also, Bruno Haible has been
making some noises about coming up with a more POSIXy way of doing
things.

--David Gadbois

[1] I actually experimented with putting a mutex around *every* load
from and store to object space.  The slowdown varied from a factor a
nine (Linux) to 60 (OSF/1).

[2] The current vogue in multiprocessor systems is to have weak
consistency constraints on memory vis-a-vis other processors.  For
example, if memory locations A and B contain 1 and 2 respectively, and
one processor writes 1' and 2' to them, another processor reading
those locations may see 1 and 2, or 1' and 2, or 1 and 2', or 1' and
2'.  This makes maintaining safety a royal PITA.
From: Hannu Koivisto
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <t2waf2fff7q.fsf@lehtori.cc.tut.fi>
David Gadbois <·······@lagavulin.cyc.com> writes:

| the ability to do safely and efficiently a global synchronization of
| all the threads.  This is necessary because there are a number of
| infrequent situations where you want to modify some global state but
| don't want to put a mutex around it for frequent non-synchronized
| accesses. [1]

Could you elaborate? What kind of infrequent situations that
need global synchronization (and can't use mutex or some similar
mechanism) of all threads are you refering to?

| They are not.  At all.  There are a couple of problems.  One is that
| the usual Lisp style threads have a view of a globally accessible and
| consistent object store.  This view just does not mesh with current
| APIs (and hardware!) that really want you to minimize global state.

But isn't minimizing the use of global state a good idea anyway?
Probably because I'm just a novice in CL, I can't see why Lisp
would be different in this respect than, say, C++. This subject
is very interesting, so if you have pointers to papers or some
other information that cover implementing OS-based thread
support for Scheme or CL, I'd be interested to know.

| Another problem is the usual quality-of-implementation expectation
| that, unless you try really hard, user code cannot damage the system
| as a whole; every error is recoverable.

OS-based thread support is especially useful for software that
needs all the power an SMP system can provide. I would assume
that such a software in its production version is compiled with
all possible safety-toggles set to minimum anyway. Would it be
completely stupid idea to use usual non-OS-based Lisp threads
during the development and use
less-tolerant-for-programming-errors OS-based threads for
compiled production code that really needs them?

| There are other multiprocessing models for Lisp that may be more
| current-trend friendly.  Check out Connection Machine Lisp and Kelly
| Murray's stuff.  There may be something to learn from how Java does

I tried to search for that Kelly Murray's stuff with Altavista
but couldn't find anything. Do you have direct URL where to find
it? I also tried searching CLISP www-site but I couldn't find
anything threads-related from Bruno Haible either.

//Hannu
From: Kelly Murray
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <3638ADF6.50B35A00@IntelliMarket.Com>
> | There are other multiprocessing models for Lisp that may be more
> | current-trend friendly.  Check out Connection Machine Lisp and Kelly
> | Murray's stuff.  There may be something to learn from how Java does
> 
> I tried to search for that Kelly Murray's stuff with Altavista
> but couldn't find anything. Do you have direct URL where to find
> it? I also tried searching CLISP www-site but I couldn't find
> anything threads-related from Bruno Haible either.

I've got two "stuffs", neither of which has any published papers.
I'm not an academic (UMass kicked me out of the PhD program..)
David Gadbois is probably refering to my Top Level Common Lisp,
which was a shared-memory, truly multiprocessor Common Lisp
(ran on Sequent, Encore, Solbourne, DG platforms) that was
a failed commercial enterprise which got buried by lawsuits (don't ask)

The implementation used Unix-level processes to achieve true
multiprocessing, but also had thread-level parallelism that
was timeshared by the larger-grained processes.
It also had fine-grained parallelism as well that was executed
by the thread-level.

These days I'm working toward distributed parallelism that
can utilize a network of workstations (i.e. a bunch of Pentium
motherboards.. ;).  The persistent object store functions as the
shared-memory.  It's much larger grained model than previous work.
I can't say more than that because it's a very long term project
that gets worked on very slowly and nobody's paying me to work on it.

-Kelly Murray  ···@intellimarket.com
From: Tim Bradshaw
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <ey3ww5j9pe8.fsf@todday.aiai.ed.ac.uk>
* David Gadbois wrote:
[Multiprocessor-friendliness of Lisp threads]

> They are not.  At all.  There are a couple of problems.  One is that
> the usual Lisp style threads have a view of a globally accessible and
> consistent object store.  This view just does not mesh with current
> APIs (and hardware!) that really want you to minimize global state.
> Another problem is the usual quality-of-implementation expectation
> that, unless you try really hard, user code cannot damage the system
> as a whole; every error is recoverable.

Although I'm not really a multiprocessor user, I got the impression
that current SMP machines do deal with global state (ie global shared
memory) reasonably thoroughly, so I'm not quite sure what you mean
here.  I know that larger-scale machines which use message-passing or
whatever do *not* deal with global state well, but it was really SMPs
I was thinking of, since they are becoming cheap and common.

Could you elaborate?

--tim
From: David Gadbois
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <w0kn26ewxbx.fsf@lagavulin.cyc.com>
Tim Bradshaw <···@aiai.ed.ac.uk> writes:
> * David Gadbois wrote:
> [Multiprocessor-friendliness of Lisp threads]
> > They are not.  At all.  There are a couple of problems.  One is
> > that the usual Lisp style threads have a view of a globally
> > accessible and consistent object store.  This view just does not
> > mesh with current APIs (and hardware!) that really want you to
> > minimize global state.  Another problem is the usual
> > quality-of-implementation expectation that, unless you try really
> > hard, user code cannot damage the system as a whole; every error
> > is recoverable.
> 
> Although I'm not really a multiprocessor user, I got the impression
> that current SMP machines do deal with global state (ie global
> shared memory) reasonably thoroughly, so I'm not quite sure what you
> mean here.

The current implementation approach for the middle-tier (the sweet
spot in price/performance) parallel machines is called ccNUMA
(cache-consistent non-uniform memory access).  It is essentially a
message-passing approach, with cache lines being the messages, that
provides a programming model that is semantically almost, but not
quite, like a machine with a bunch of cacheless processors talking to
a shared memory.

The big problem is write buffers.  Since there is such a huge mismatch
between the speed of processors and that of the lower levels of the
cache hierarchy, the consistency protocols don't even get to see the
data in program order:  Writes can hang around on-chip for a while
before they are flushed out to cache in an order that may be
independent of program order.  The buffers can be explicitly flushed,
but that eats into the the premium you pay for the parallelism.

> I know that larger-scale machines which use message-passing or
> whatever do *not* deal with global state well, but it was really
> SMPs I was thinking of, since they are becoming cheap and common.

I am not sure about this last point.  It is hardly worth the effort to
do fine-grained parallelism [1] for small degrees of parallelism, say
x2 or x4.  It gets interesting above that level, but it is hardly in
the best interest of the chip vendors to encourage folks to throw
together big systems with lots of cheap, low-margin chips versus
encouraging small or medium systems with a few expensive, high-margin
parts.  Intel certainly seems to be doing this with their pricing and
MP support.

--David Gadbois

[1] Coarse task-level parallelism, sure, but that is not what goes
into the usual Lisp style threads.
From: Tim Bradshaw
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <ey3vhl29rhm.fsf@todday.aiai.ed.ac.uk>
* David Gadbois wrote:
> [I wrote]
>> I know that larger-scale machines which use message-passing or
>> whatever do *not* deal with global state well, but it was really
>> SMPs I was thinking of, since they are becoming cheap and common.

> I am not sure about this last point.  It is hardly worth the effort to
> do fine-grained parallelism [1] for small degrees of parallelism, say
> x2 or x4.  It gets interesting above that level, but it is hardly in
> the best interest of the chip vendors to encourage folks to throw
> together big systems with lots of cheap, low-margin chips versus
> encouraging small or medium systems with a few expensive, high-margin
> parts.  Intel certainly seems to be doing this with their pricing and
> MP support.

I think I may not have made clear what I meant by `cheap'.  I *think*
I meant that you can now get n-cpu shared-memory (however implemented)
machines for values of n up to 64 (or larger?) which are not *vastly*
expensive, and run conventional OSs in a fairly conventional way.
These boxes are really designed for big database systems but they
would also do quite well for things like big web server-type
applications where the threading demands (synchronisation /coherency
demands really) are not that hairy.  So I think my definition of cheap
is `actually quite expensive', but I'm also interested in a rather
boring multithreaded system probably -- something you could really do
with multiple Unix processes if you really had to, but it would be a
pain.

--tim
From: David Steuber "The Interloper
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <363733fc.8527622@news.newsguy.com>
On 25 Oct 1998 10:36:41 GMT, ········@not.mailable (Martin Cracauer)
claimed or asked:

% http://www.cons.org/cracauer/lisp-threads.html is an overview of
% existing thread interfaces for Common Lisp. CMUCL 18b on x86
% implements something similar to the portable interface in the CLIM
% specification.

Thanks!

% >% Suspending is not possible with conventional Posix-threads :-(.
% 
% >Can Lisp (I know, see cons.org) do it's own threading, or is the OS
% >required?  Java manages it somehow.  Or maybe it doesn't.
% 
% All Common Lisp systems in wider distribution implement threads
% internally, no Unix or Win32 kernel support is used, OS-supplied
% libraries for C interfaces aren't used as a base.

Interesting.  This implies that the threading model can be implemented
purely in Lisp and should therefor be portable.  I'm not sure how an
SMP architecture would be supported though.  I don't know if Java can
take advantage of SMP yet either.

Not that it matters.  The real advantage of SMP as I see it is that it
saves space over a bunch of computers working in parallel.

So, when is the Linux x86 version going to be moved up to the same
class as the 18b stuff and the other Unixen stuff?  I don't know if
Linux is the best x86 Unix out there or not, but I dare say it is the
most popular and is gaining market share faster than other OSs.

I am of course referring to the Linux port siting in the experimental
tree :-).

It looks to me like CMUCL is in basically three parts:

1) the C/Assembler CPU/OS dependant loader
2) the Lisp in Lisp
3) the Python compiler that seems to have a separate version for each
target CPU (OS?).

If I am remotely correct, about how much falls in part 2?  Would
threading be in there?  I am not yet ready for the rigors of real code
:-)

I am just trying to get a feel for the effort involved in porting.  I
don't know how much of lisp can be architecture neutral and how much
is dependant on the OS/CPU.

I am hoping that the larger part of Lisp is completely portable.  I am
also hoping that can port across all systems supported by CMUCL by
simply cross-compiling code.

While Java is searching for WORA, I will be happy with "Write once,
compile for each target."

BTW, I mailed you the session and dbg back trace you asked for.  You
should see it in your mail box before you get to this message.

--
David Steuber (ver 1.31.2a)
http://www.david-steuber.com
To reply by e-mail, replace trashcan with david.

"Ignore reality there's nothing you can do about it..."
-- Natalie Imbruglia "Don't you think?"
From: Christopher J. Vogt
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <3635E2A4.E9B56D00@computer.org>
David Steuber The Interloper wrote:
> 
> On 25 Oct 1998 10:36:41 GMT, ········@not.mailable (Martin Cracauer)
> claimed or asked:
[...]
> 
> %
> % >Can Lisp (I know, see cons.org) do it's own threading, or is the OS
> % >required?  Java manages it somehow.  Or maybe it doesn't.
> %
> % All Common Lisp systems in wider distribution implement threads
> % internally, no Unix or Win32 kernel support is used, OS-supplied
> % libraries for C interfaces aren't used as a base.
> 
> Interesting.  This implies that the threading model can be implemented
> purely in Lisp and should therefor be portable.  I'm not sure how an
> SMP architecture would be supported though.  I don't know if Java can
> take advantage of SMP yet either.

Java does take advantage of SMP, at least under Windows using (pick one):
Sun, Symantec,  Netscape on my SMP machine.

> Not that it matters.  The real advantage of SMP as I see it is that it
> saves space over a bunch of computers working in parallel.

And money, and time.

[...]
-- 
Christopher J. Vogt - Computer Consultant - Solving hard problems since 1979
http://members.home.com/vogt/
From: Rainer Joswig
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <joswig-2710982331540001@194.163.195.67>
> % All Common Lisp systems in wider distribution implement threads
> % internally, no Unix or Win32 kernel support is used, OS-supplied
> % libraries for C interfaces aren't used as a base.

MCL uses OS threads. Genera, too. ;-)

-- 
http://www.lavielle.com/~joswig
From: Raymond Toy
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <m2af2he6qf.fsf@lorien.users.mindspring.com>
>>>>> "David" == David Steuber "The Interloper" <········@david-steuber.com> writes:

    David> So, when is the Linux x86 version going to be moved up to
    David> the same class as the 18b stuff and the other Unixen stuff?

I'm not sure what you mean by this.  The x86 version is ahead of 18b
and other Unix ports of CMUCL.  Only the x86 version has long-floats,
threading, and generational GC.

    David> I am of course referring to the Linux port siting in the
    David> experimental tree :-).

I have up-to-date Linux binary versions of the experimental sources
for both libc5 and libc6.  I'm just waiting for my one-time passwords
so I can upload them to www.cons.org.

    David> It looks to me like CMUCL is in basically three parts:

    David> 1) the C/Assembler CPU/OS dependant loader
    David> 2) the Lisp in Lisp
    David> 3) the Python compiler that seems to have a separate
    David>    version for each
    David> target CPU (OS?).

This is my understanding of CMUCL.

    David> If I am remotely correct, about how much falls in part 2?
    David> Would threading be in there?  I am not yet ready for the
    David> rigors of real code :-)

Almost all of it is in Lisp.  The threading is certainly there,
including some assembly code (in CMUCL's assembly code language).
This is used to copy stack frames and binding stacks for the different 
threads.  Some support may be in C, but I'm not sure.

    David> I am just trying to get a feel for the effort involved in
    David> porting.  I don't know how much of lisp can be architecture
    David> neutral and how much is dependant on the OS/CPU.

CMUCL is somewhat architecture neutral.  As I understand it, the
compiler works with a virtual machine model, and each architecture has
to supply a set of VOP's (virtual ops) that actually implements the
virtual machine.  It is far easier to port CMUCL to another OS than to
another CPU.  For another CPU, you have to tell CMUCL the entire
instruction set and create all of the VOP's.  In essence, you write an
assembler and a bunch of utility routines.  I have no idea how to
bootstrap such a thing.

    David> I am hoping that the larger part of Lisp is completely
    David> portable.  I am also hoping that can port across all
    David> systems supported by CMUCL by simply cross-compiling code.

Not exactly sure what you mean by "completely portable".
Cross-compiling does solve many problems, but, unfortunately, not all
of them.  For example, you cannot cross-compile a pure 18b version
from the latest experimental version of the x86 port.

-- 
---------------------------------------------------------------------------
----> Raymond Toy	····@mindspring.com
                        http://www.mindspring.com/~rtoy
From: David Steuber "The Interloper
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <3638bb3d.174224962@news.newsguy.com>
On 27 Oct 1998 21:54:32 -0500, Raymond Toy <····@mindspring.com>
claimed or asked:


% >>>>> "David" == David Steuber "The Interloper" <········@david-steuber.com> writes:
% 
%     David> So, when is the Linux x86 version going to be moved up to
%     David> the same class as the 18b stuff and the other Unixen stuff?
% 
% I'm not sure what you mean by this.  The x86 version is ahead of 18b
% and other Unix ports of CMUCL.  Only the x86 version has long-floats,
% threading, and generational GC.

Like I said below, I was referring to the fact that the x86 version
was 'experimental.  I was told that the long-float version was old.  I
ended up using cmucl-2_4_5-2-lib5.tgz.

I am surprised that what is described as 18a+ is ahead of 18b.  It
doesn't surprise me that x86 versions would move ahead of other CPU
architectures because of the simple fact that there are more x86s
around to play on.

%     David> I am of course referring to the Linux port siting in the
%     David> experimental tree :-).
% 
% I have up-to-date Linux binary versions of the experimental sources
% for both libc5 and libc6.  I'm just waiting for my one-time passwords
% so I can upload them to www.cons.org.

I am looking forward to this.  Yep, I am a compulsive upgrader.  I'm
sure Microsoft used to love me before I upgraded from NT to Linux.
 
% CMUCL is somewhat architecture neutral.  As I understand it, the
% compiler works with a virtual machine model, and each architecture has
% to supply a set of VOP's (virtual ops) that actually implements the
% virtual machine.  It is far easier to port CMUCL to another OS than to
% another CPU.  For another CPU, you have to tell CMUCL the entire
% instruction set and create all of the VOP's.  In essence, you write an
% assembler and a bunch of utility routines.  I have no idea how to
% bootstrap such a thing.

This is the part I still don't get.  I won't rehash here what I have
said in the compiling cmucl thread.  Maybe it will seep into my brain
eventually.

%     David> I am hoping that the larger part of Lisp is completely
%     David> portable.  I am also hoping that can port across all
%     David> systems supported by CMUCL by simply cross-compiling code.
% 
% Not exactly sure what you mean by "completely portable".
% Cross-compiling does solve many problems, but, unfortunately, not all
% of them.  For example, you cannot cross-compile a pure 18b version
% from the latest experimental version of the x86 port.

In my case, "completely portable" means that I could simply recompile
my application on another cmucl implementation without altering my
source code in any way to get it to run on say a sparc or hp.  Better
yet would be the ability to target any platform that python knows
about.  Then I could build a sparc version on my x86 box.

Craig Brozefsky already flamed me for confessing that I don't know all
the issues involved in porting or building cmucl or building
applications designed to run completely separate from a lisp
environment (like the C model of application building).

It does me no end of good to know that I can be flamed for asking
questions about things that are several levels ahead of my current
understanding.  Why encourage me to continue learning Lisp?  I guess
I'm not expected to ever be able to give something back.

I didn't say it in the other post, but Craig can consider my
enthusiasm slightly wilted from the heat.

--
David Steuber (ver 1.31.2a)
http://www.david-steuber.com
To reply by e-mail, replace trashcan with david.

"Ignore reality there's nothing you can do about it..."
-- Natalie Imbruglia "Don't you think?"
From: Craig Brozefsky
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <8767d2vapc.fsf@duomo.pukka.org>
········@david-steuber.com (David Steuber "The Interloper") writes:
> In my case, "completely portable" means that I could simply recompile
> my application on another cmucl implementation without altering my
> source code in any way to get it to run on say a sparc or hp.  Better
> yet would be the ability to target any platform that python knows
> about.  Then I could build a sparc version on my x86 box.

You can pretty much do this, barring a few features which are
implemented on only one or another OS/CPU combos.  Now if you wanna
target another platform that Python knows about from a CMUCL
implementation, then you have to set up the cross-compiler.  The
porting problems mentioned above are between different versions of
cmucl, different feature sets etc, not just different platforms.  Yes,
you can build the sparc version on your x86.

> Craig Brozefsky already flamed me for confessing that I don't know all
> the issues involved in porting or building cmucl or building
> applications designed to run completely separate from a lisp
> environment (like the C model of application building).

C applications run with a libc and other support libraries, it's just
that they are "always already there", so I'm a bit perplexed about how
it's supposed to run seperate from a C environment.  What exactly do
you mean here?

Besides, I gibbed you for making a statement about something you had
just said you had little to no knowledge of, not for asking a
question.

> I didn't say it in the other post, but Craig can consider my
> enthusiasm slightly wilted from the heat.

Great, now I won't be able to sleep tonite, thanx alot.
From: David Steuber "The Interloper
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <36417974.353991282@news.newsguy.com>
On Thu, 29 Oct 1998 06:10:55 GMT, Craig Brozefsky <·····@onshore.com>
claimed or asked:
 
% C applications run with a libc and other support libraries, it's just
% that they are "always already there", so I'm a bit perplexed about how
% it's supposed to run seperate from a C environment.  What exactly do
% you mean here?

In the Windows world (a place I am trying to escape from), C
applications each carry their own runtime with them.  They do still
rely on system dlls of course.  I wasn't aware that it was standard
Unix practice to have a shared library for the C runtime code.  That
is great for eliminating redundancy.  But what happens when the shared
library gets updated?  Most of the instability in NT or Win95/98 comes
from stomping on shared system dlls.  You install an app that breaks
others.  In any case, what I am after is the ability to build a single
executable binary image that can be copied onto another machine that
does not have cmucl installed, and run it.  Presumably that means
embedding some startup code and a runtime in the image.
 
% Besides, I gibbed you for making a statement about something you had
% just said you had little to no knowledge of, not for asking a
% question.

When I don't know about something, I will try to speculate as to how
it might be done.  At least I don't try to come of as authoritative on
the subject as a politician does.  Still, I think I was after
information or something.
 
% > I didn't say it in the other post, but Craig can consider my
% > enthusiasm slightly wilted from the heat.
% 
% Great, now I won't be able to sleep tonite, thanx alot.

3mg of Melatonin, 50 mg of diphenhydramine, 20mg Paxil, 1mg
Alprazolam, and a pint of stout with a shot of bourbon should fix
that.  I hope you don't have to wake up early.  That combo will knock
you out for a while.  Works for me.  Sometimes.

--
David Steuber (ver 1.31.2a)
http://www.david-steuber.com
To reply by e-mail, replace trashcan with david.

"Ignore reality there's nothing you can do about it..."
-- Natalie Imbruglia "Don't you think?"
From: rusty craine
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <71er00$epu$1@excalibur.flash.net>
>3mg of Melatonin, 50 mg of diphenhydramine, 20mg Paxil, 1mg
>Alprazolam, and a pint of stout with a shot of bourbon should fix
>that.  I hope you don't have to wake up early.  That combo will knock
>you out for a while.  Works for me.  Sometimes.


As this news group's defacto pharmacist this is a combination I would not
suggest,  unless of course you are institutionalized.  EtOH and
benzodiazapams is not a good idea (alprazolam esp 1mg).

You take care of the programming. Direct all pharmaceutical questions to
········@flash.net.
hope you were joking
rusty
From: David Steuber "The Interloper
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <363ee1f2.4397693@news.newsguy.com>
On Sat, 31 Oct 1998 05:08:29 -0600, "rusty craine"
<········@flash.net> claimed or asked:

% You take care of the programming. Direct all pharmaceutical questions to
% ········@flash.net.
% hope you were joking
% rusty

Yeah.  Alcohol is strictly verboten.  I hope a beer now and then
doesn't hurt.

Do asylums offer internet connectivity?  Of course they do!  How else
does one explain ·······@hotmail.com?

--
David Steuber (ver 1.31.2a)
http://www.david-steuber.com
To reply by e-mail, replace trashcan with david.

"Ignore reality there's nothing you can do about it..."
-- Natalie Imbruglia "Don't you think?"
From: Stig Hemmer
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <ekv7lxfuw0b.fsf@gnoll.pvv.ntnu.no>
········@david-steuber.com (David Steuber "The Interloper") writes:
> I wasn't aware that it was standard Unix practice to have a shared
> library for the C runtime code.  That is great for eliminating
> redundancy.  But what happens when the shared library gets updated?

In some Unixen, everything keeps working nicely with the new library.

In some Unixen, most programs break severely and need to be recompiled
for the new library.

This technology is still in its infancy and needs some years still to
be stable.  (Or, to be more correct: For the industry to reallize
which type of shared libraries are superior and to use that type
exclusively)

Stig Hemmer,
Jack of a Few Trades.
From: Steve Gonedes
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <m2emrlpc81.fsf@KludgeUnix.com>
········@david-steuber.com (David Steuber "The Interloper") writes:

< On Thu, 29 Oct 1998 06:10:55 GMT, Craig Brozefsky <·····@onshore.com>
< claimed or asked:
<  
< % C applications run with a libc and other support libraries, it's just
< % that they are "always already there", so I'm a bit perplexed about how
< % it's supposed to run seperate from a C environment.  What exactly do
< % you mean here?
< 
< In the Windows world (a place I am trying to escape from), C
< applications each carry their own runtime with them.  They do still
< rely on system dlls of course.  I wasn't aware that it was standard
< Unix practice to have a shared library for the C runtime code.  That
< is great for eliminating redundancy.  But what happens when the shared
< library gets updated?

Hopefully nothing :)

echo *

In most linux distros there is a program called sln in case you remove
the wrong symlink. The `s' is for statically linked (so it seems at
least), I have no idea what the `ln' stands for (I use `link' - but
this is probably not a portable solution).

A quick joke about portability. Was just playing with tcsetattr, which
apparently allows you to dial out for pizza using a CRT or a line
printer. Anyway, tcsetattr returns success if the call did what you
wanted it to do. The funny thing is that in order to be
posixly-correct, the function should return success even if the call
partially failed (i.e., it didn't work); where success is defined as
failure and failure is less than correct but not in danger of being
truncated. I thought it was funny, in a perverted unix kinda way...

< Most of the instability in NT or Win95/98 comes
< from stomping on shared system dlls.  You install an app that breaks
< others.  In any case, what I am after is the ability to build a single
< executable binary image that can be copied onto another machine that
< does not have cmucl installed, and run it.  Presumably that means
< embedding some startup code and a runtime in the image.

[and in reference to a note in another one of your posts]

Something else you may want to check into one day about cmu-cl. You
can probably replace the repl with some app-specific code so that the
`lisp' could have a more attractive/less programmer-like interface. I
don't know how hard this would be - I think the repl is in a single
file (written in lisp), so it may not be that difficult (it may have
already been done for the x interfaces, I dunno). Just food for
thought...
From: David Steuber "The Interloper
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <363fbfe5.192288376@news.newsguy.com>
On 3 Nov 1998 05:46:57 GMT, Steve Gonedes <········@worldnet.att.net>
claimed or asked:

% Something else you may want to check into one day about cmu-cl. You
% can probably replace the repl with some app-specific code so that the
% `lisp' could have a more attractive/less programmer-like interface. I
% don't know how hard this would be - I think the repl is in a single
% file (written in lisp), so it may not be that difficult (it may have
% already been done for the x interfaces, I dunno). Just food for
% thought...

I'm afraid I don't know what 'repl is.

The user interface will be a combination of graphical (menus, tool
bar, possibly some hideable pallets) and a command window.  The
command window will also be hideable.  The menus and tool bar buttons
will have the effect of issuing commands, much like in (X)Emacs.  In
fact, I can bind a lot of keys to commands, not to mention the mouse.

If I do the job right, then a pure artist should not need to ever type
in a command.  At the same time, the more engineering type user will
be able to enter commands, functions, complete programs, etc to
achieve a desired effect.

In a very real sense, the program will be a CASE tool for generating
Lisp code that makes calls into an extensible library to describe
models.  The UI will be to syntactic sugar what icing is to a cake.

There is nothing new in any of this.  The ideas are lifted directly
from Emacs, Renderman, POV-Ray, Rational Rose, etc.  It's just another
wrapper to provide a human friendly (I hope) interface to a Lisp
system that has been enhanced (again, I hope) to draw pictures.

Since I think of nothing new, someone must already have a product that
does exactly this.

--
David Steuber (ver 1.31.2a)
http://www.david-steuber.com
To reply by e-mail, replace trashcan with david.

"Ignore reality there's nothing you can do about it..."
-- Natalie Imbruglia "Don't you think?"
From: Marco Antoniotti
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <lw1znjx4al.fsf@copernico.parades.rm.cnr.it>
········@david-steuber.com (David Steuber "The Interloper") writes:

> 
> There is nothing new in any of this.  The ideas are lifted directly
> from Emacs, Renderman, POV-Ray, Rational Rose, etc.  It's just another
> wrapper to provide a human friendly (I hope) interface to a Lisp
> system that has been enhanced (again, I hope) to draw pictures.
> 

Which in turn were lifted from Xerox Interlisp machines and Symbolics
and LMI Lisp Machines :)

-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - (0)6 - 68 10 03 16, fax. +39 - (0)6 - 68 80 79 26
http://www.parades.rm.cnr.it
From: Gareth McCaughan
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <86zpa71qrk.fsf@g.pet.cam.ac.uk>
David Steuber wrote:

> I'm afraid I don't know what 'repl is.

"Read-eval-print loop". In other words, the thing that lets you
type in Lisp forms, evaluates them, and tells you what the results
were.

-- 
Gareth McCaughan       Dept. of Pure Mathematics & Mathematical Statistics,
·····@dpmms.cam.ac.uk  Cambridge University, England.
From: David Steuber "The Interloper
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <364511df.278810558@news.newsguy.com>
On 04 Nov 1998 14:22:55 +0000, Gareth McCaughan
<·····@dpmms.cam.ac.uk> claimed or asked:

% > I'm afraid I don't know what 'repl is.
% 
% "Read-eval-print loop". In other words, the thing that lets you
% type in Lisp forms, evaluates them, and tells you what the results
% were.

Yet another acronym to remember.  ITILMM!

--
David Steuber (ver 1.31.2a)
http://www.david-steuber.com
To reply by e-mail, replace trashcan with david.

"Ignore reality there's nothing you can do about it..."
-- Natalie Imbruglia "Don't you think?"
From: Martin Cracauer
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <717nfg$3gf$1@counter.bik-gmbh.de>
········@david-steuber.com (David Steuber "The Interloper") writes:

>On 25 Oct 1998 10:36:41 GMT, ········@not.mailable (Martin Cracauer)
>claimed or asked:
>% >% Suspending is not possible with conventional Posix-threads :-(.
>% 
>% >Can Lisp (I know, see cons.org) do it's own threading, or is the OS
>% >required?  Java manages it somehow.  Or maybe it doesn't.
>% 
>% All Common Lisp systems in wider distribution implement threads
>% internally, no Unix or Win32 kernel support is used, OS-supplied
>% libraries for C interfaces aren't used as a base.

>Interesting.  This implies that the threading model can be implemented
>purely in Lisp and should therefor be portable.  

Sorry, that's nonsense. It is implemented in machine terms that cannot
be (efficiently) expressed in portable Common Lisp. Threads are
implemented as little hooks in the machine-dependent runtime written
in C with highler-level interfaces being implement in Lisp.

>I'm not sure how an
>SMP architecture would be supported though.  I don't know if Java can
>take advantage of SMP yet either.

Those Java implementation with OS threads (i.e. Solaris 2, Win32)
can. 

>So, when is the Linux x86 version going to be moved up to the same
>class as the 18b stuff and the other Unixen stuff?  I don't know if
>Linux is the best x86 Unix out there or not, but I dare say it is the
>most popular and is gaining market share faster than other OSs.

CMUCL binaries don't falls of the trees. No CMUCL developer is
supposed to produce binaries he don't need or want by himself. 

The CMUCL project isn't after market share so why should it matter how
much users an OS has. If it mattered, we'd support Win32 first. We all
put up those binaries we happen to have or need for some reason.

So either you ask Peter or Ray to do you the favour or you'll have to
wait for the next release one of them puts out.

>It looks to me like CMUCL is in basically three parts:

>1) the C/Assembler CPU/OS dependant loader

It's a little more than just loading. Much of of garbage collectors,
symbol lookup, much of the debuggers are also part of this (the lisp/
directory in the CMUCL src tree).

>2) the Lisp in Lisp

That's the code/ subdir. It also has the Lisp parts of the lowlevel stuff.

>3) the Python compiler that seems to have a separate version for each
>target CPU (OS?).

Most of the compiler is shared amoung the architectures.

>If I am remotely correct, about how much falls in part 2?  Would
>threading be in there?  

As I said, threading is deeply rooted in the runtime, it isn't
portable Common Lisp.

[...]
>While Java is searching for WORA, I will be happy with "Write once,
>compile for each target."

You're comparing apples to oranges here. Lisp programs are portable
amoung all CMUCL ports, with few exceptions like threads that aren't
implemented on all platforms. 

The Java runtime is as unportable as the CMUCL system.

>BTW, I mailed you the session and dbg back trace you asked for.  You
>should see it in your mail box before you get to this message.

Yes, thanks. I'm afraid the backtrace didn't say more than "I'm
dead". I think it's time to work on the Solaris2 port a little more.

Martin
From: Mike McDonald
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <717sjr$fnt$1@spitting-spider.aracnet.com>
In article <············@counter.bik-gmbh.de>,
	········@not.mailable (Martin Cracauer) writes:

> So either you ask Peter or Ray to do you the favour or you'll have to
> wait for the next release one of them puts out.

  Except of course, binaries aren't ever generated for the "releases".

  Mike McDonald
  ·······@mikemac.com
From: David Steuber "The Interloper
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <3639c0dd.175664642@news.newsguy.com>
On 28 Oct 1998 18:23:44 GMT, ········@not.mailable (Martin Cracauer)
claimed or asked:

% >% All Common Lisp systems in wider distribution implement threads
% >% internally, no Unix or Win32 kernel support is used, OS-supplied
% >% libraries for C interfaces aren't used as a base.
% 
% >Interesting.  This implies that the threading model can be implemented
% >purely in Lisp and should therefor be portable.  
% 
% Sorry, that's nonsense. It is implemented in machine terms that cannot
% be (efficiently) expressed in portable Common Lisp. Threads are
% implemented as little hooks in the machine-dependent runtime written
% in C with highler-level interfaces being implement in Lisp.

Ah.  What you say makes sense to me.  So this means that it is
possible to get cmucl to take advantage of SMP if the underlying
support is there.  I think.
 
% >So, when is the Linux x86 version going to be moved up to the same
% >class as the 18b stuff and the other Unixen stuff?  I don't know if
% >Linux is the best x86 Unix out there or not, but I dare say it is the
% >most popular and is gaining market share faster than other OSs.
% 
% CMUCL binaries don't falls of the trees. No CMUCL developer is
% supposed to produce binaries he don't need or want by himself. 
% 
% The CMUCL project isn't after market share so why should it matter how
% much users an OS has. If it mattered, we'd support Win32 first. We all
% put up those binaries we happen to have or need for some reason.
% 
% So either you ask Peter or Ray to do you the favour or you'll have to
% wait for the next release one of them puts out.

Well, I do hope that eventually I will understand the system well
enough that I can implement things I need that are missing myself and
be able to contribute them back to the project, if others want them.

I am not trying to imply that the Peter, Ray, or anyone else should
give me free support simply because I want it.  Clearly that would be
absurd.  If I bought a commercial Lisp, that would be another story.

% >It looks to me like CMUCL is in basically three parts:
% 
% >1) the C/Assembler CPU/OS dependant loader
% 
% It's a little more than just loading. Much of of garbage collectors,
% symbol lookup, much of the debuggers are also part of this (the lisp/
% directory in the CMUCL src tree).
% 
% >2) the Lisp in Lisp
% 
% That's the code/ subdir. It also has the Lisp parts of the lowlevel stuff.
% 
% >3) the Python compiler that seems to have a separate version for each
% >target CPU (OS?).
% 
% Most of the compiler is shared amoung the architectures.

Thanks for telling me where to look.  I doubt I would understand it
today, but my hope is that someday I will.
 
% >BTW, I mailed you the session and dbg back trace you asked for.  You
% >should see it in your mail box before you get to this message.
% 
% Yes, thanks. I'm afraid the backtrace didn't say more than "I'm
% dead". I think it's time to work on the Solaris2 port a little more.

I'm sorry the information wasn't helpful.  If I understood things
better, and had the time at work (would you believe they expect me to
produce results?), perhaps I could be of more help.

I'm currently climbing two mountains, lisp and linux.  I'm sure that
effort is easier than getting into the gory details of
compiler/interpreter design and implementation.

While I do hope to be able to return something to cmucl at some point
in the fairly distant future, I am a selfish human being who will use
what's available first.  I hope no one blames me for that.  However,
at the moment, it seems to be in my best interest that cmucl runs well
under Linux x86.  If I am lucky enough, perhaps I will be able to
further that cause.

--
David Steuber (ver 1.31.2a)
http://www.david-steuber.com
To reply by e-mail, replace trashcan with david.

"Ignore reality there's nothing you can do about it..."
-- Natalie Imbruglia "Don't you think?"
From: Tim Bradshaw
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <ey31znrbr38.fsf@todday.aiai.ed.ac.uk>
* David Steuber "The Interloper" wrote:

> Ah.  What you say makes sense to me.  So this means that it is
> possible to get cmucl to take advantage of SMP if the underlying
> support is there.  I think.
 
No, that may not be true (or rather, yes it's true, but it may be very
hard).  Typically the only way of having threads that get scheduled on
multiple processors is to use the threads that the OS supports --
because only the OS knows how to to the multiple-processor stuff.

So you need the Lisp threads to be built on top of the OS threads in
some way, which means that the OS thread stuff needs to be rich enough
that building Lisp threads on top of them is possible to do.  I
suspect that the main issue there is dealing with things that need to
happen on thread switches, perhaps rebinding special variables, or
calling Lisp code to establish whether threads are runnable &c.

That's requiring a lot more than some basic low-level support on which
you can build a Lisp-only threading system -- I think arranging for
timed interrupts to the Lisp system is probably more-or-less enough to
do that.

--tim
From: David Steuber "The Interloper
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <36427e24.355191318@news.newsguy.com>
On 29 Oct 1998 10:27:39 +0000, Tim Bradshaw <···@aiai.ed.ac.uk>
claimed or asked:

% That's requiring a lot more than some basic low-level support on which
% you can build a Lisp-only threading system -- I think arranging for
% timed interrupts to the Lisp system is probably more-or-less enough to
% do that.

It sounds pretty darn complicated.  I will have to revisit the topic
in a year or so.  Meanwhile, I think my time maybe much better spent
trying to just understand CL.

--
David Steuber (ver 1.31.2a)
http://www.david-steuber.com
To reply by e-mail, replace trashcan with david.

"Ignore reality there's nothing you can do about it..."
-- Natalie Imbruglia "Don't you think?"
From: Martin Cracauer
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <70t5t9$cdb$1@counter.bik-gmbh.de>
········@david-steuber.com (David Steuber "The Interloper") writes:

>While testing the Sparc installation of CMUCL, I wrote a normal
>recursive form of the factorial function, specifically:

>(defun fact (n)
>	(if (< n 2)
>		1
>		(* n fact(- n 1))))

>(fact 1000) returned a nice large number.
>(fact 2000) triggered a segment fault, and lisp dumped core.  I
>thought this couldn't happen?

The SunOS 5 of CMUCL is still not as robust as the other versions (the
SunOS 4 version doesn't have these problems).

Did you run this compiled or interpreted? Could you please send a
complete transcript of the crashing session, including every Lisp
expression your local Lisp executes that isn't part of the CMUCL
binary (could mean including your ~/.cmucl.lisp or ~/init.lisp)

The C startup code of CMUCL binaries is usually compiled with
debugging enabled. It would be of great help if you sent a backtrace
of gdb (yes, the C debugger :-).

Do it like this:
Unpack the lisp/ subdirectory of the 18b sources
Switch into the dir the C files are in.
> gdb /usr/local/lib/cmucl/bin/lisp <or whereever your binary is
(gdb) r <whatver parameters you use>
* <your lisp code>
[segfault]
(gdb) bt
[gdb showing the backtrace we need]

And a request to everyone: Please do not name the mailing addresses of
the cons.org mailing list in public fourums. Refer to the web pages at
www.cons.org/cmucl/

Thanks
Martin
From: David Steuber "The Interloper
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <3639634e.10197703@news.newsguy.com>
On 24 Oct 1998 18:22:33 GMT, ········@not.mailable (Martin Cracauer)
claimed or asked:

e-mailing this to myself at work :-)

% ········@david-steuber.com (David Steuber "The Interloper") writes:
% 
% >While testing the Sparc installation of CMUCL, I wrote a normal
% >recursive form of the factorial function, specifically:
% 
% >(defun fact (n)
% >	(if (< n 2)
% >		1
% >		(* n fact(- n 1))))
% 
% >(fact 1000) returned a nice large number.
% >(fact 2000) triggered a segment fault, and lisp dumped core.  I
% >thought this couldn't happen?
% 
% The SunOS 5 of CMUCL is still not as robust as the other versions (the
% SunOS 4 version doesn't have these problems).
% 
% Did you run this compiled or interpreted? Could you please send a
% complete transcript of the crashing session, including every Lisp
% expression your local Lisp executes that isn't part of the CMUCL
% binary (could mean including your ~/.cmucl.lisp or ~/init.lisp)
% 
% The C startup code of CMUCL binaries is usually compiled with
% debugging enabled. It would be of great help if you sent a backtrace
% of gdb (yes, the C debugger :-).
% 
% Do it like this:
% Unpack the lisp/ subdirectory of the 18b sources
% Switch into the dir the C files are in.
% > gdb /usr/local/lib/cmucl/bin/lisp <or whereever your binary is
% (gdb) r <whatver parameters you use>
% * <your lisp code>
% [segfault]
% (gdb) bt
% [gdb showing the backtrace we need]
% 
% And a request to everyone: Please do not name the mailing addresses of
% the cons.org mailing list in public fourums. Refer to the web pages at
% www.cons.org/cmucl/
% 
% Thanks
% Martin

The binary version I installed at work was from CMU.  If that is the
same as the one on cons.org, I will get that information to you at
some point.

I still have some fiddling to do with the Sparc set up.  I was running
in the top-level with no hemlock or emacs (aka "you deserve to lose").

I am hoping to get reasonably similar versions at work and at home.
On problem is with CLM.  I can't install it on my home machine due to
a missing .so file.  Other than that, I don't have root access to the
work machine.

--
David Steuber (ver 1.31.2a)
http://www.david-steuber.com
To reply by e-mail, replace trashcan with david.

"Ignore reality there's nothing you can do about it..."
-- Natalie Imbruglia "Don't you think?"
From: Martin Cracauer
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <70v0te$hnd$1@counter.bik-gmbh.de>
········@david-steuber.com (David Steuber "The Interloper") writes:

>On 24 Oct 1998 18:22:33 GMT, ········@not.mailable (Martin Cracauer)
>claimed or asked:

>e-mailing this to myself at work :-)

>% ········@david-steuber.com (David Steuber "The Interloper") writes:
>% 
>% >While testing the Sparc installation of CMUCL, I wrote a normal
>% >recursive form of the factorial function, specifically:
>% 
>% >(defun fact (n)
>% >	(if (< n 2)
>% >		1
>% >		(* n fact(- n 1))))
>% 
>% >(fact 1000) returned a nice large number.
>% >(fact 2000) triggered a segment fault, and lisp dumped core.  I
>% >thought this couldn't happen?
>% 
>% The SunOS 5 of CMUCL is still not as robust as the other versions (the
>% SunOS 4 version doesn't have these problems).
>% 
>% Did you run this compiled or interpreted? 

I just tested, you're running interpreted. Compiling the code pushed
the limit.

Anyway, code as this must fail at some limit, because the stack isn't
endless. The problem with the SunOS 5 version of CMUCL is that it
doesn't take you to the debugger, but just let the OS exits the
process.

But even if it would take you to the debugger, the usefulness would be
limited. By definition, there is no save way to recover from a
segmentation violation, unless you are absolutely sure that all
runaway memory references were harmless. You are running on top of a
potentioally randomly modified memory image and you can't savely
proceed with your work.

In C on Unix, people often probe potentionally junk pointers by
setjmp/signal(SIGSEGV) and then longjumping out of the signal handler
in the case of an error. If it is done right, there is just one memory
access operation in the code and you know that nothing else may have
been damaged. Afterwards you know if the pointer points to legal
memory and may proceed inspecting the data it points to for validity.

I can't imagine doing the same to protect from a stack overflow in
general and escpecially not in somewhat portable Lisp. 

Unwinding the stack up to the toplevel instruction that started the
stack hog is imaginable, but is difficult to implement. For starters,
you must tell the stack overflow from other segmentation violations.
Whatever code you use for the debugger that is jumped into on stack
overflow must not use the stack. 

[...]
>I still have some fiddling to do with the Sparc set up.  I was running
>in the top-level with no hemlock or emacs (aka "you deserve to lose").

http://www2.cons.org:8000/ftp-area/cmucl/release/cmucl-18b.sparc.solaris24.extra.tgz

contains CLX, Motif and Hemlock. This may be part of the Linux
distribution, but other CMUCL ports have to load the "extra" package
to get more than basic Common Lisp, the compiler and PCL.

>I am hoping to get reasonably similar versions at work and at home.
>On problem is with CLM.  I can't install it on my home machine due to
>a missing .so file.  Other than that, I don't have root access to the
>work machine.

If you told us which .so file is missing, and which platform you are
on [you know the rest]. It's probably Motif, in that case you have to
a Motif implementation, while Lesstif may or may not work as a binary
plug-in for the real Motif. Ask Peter. You could also compile the CLM
daemon yourself and link it to Lesstif. You don't need to rebuild
CMUCL for that.

Martin
From: David Steuber "The Interloper
Subject: Re: CMUCL on the sly (and threads)
Date: 
Message-ID: <36383a55.10152808@news.newsguy.com>
On 25 Oct 1998 11:09:34 GMT, ········@not.mailable (Martin Cracauer)
claimed or asked:

% >I am hoping to get reasonably similar versions at work and at home.
% >On problem is with CLM.  I can't install it on my home machine due to
% >a missing .so file.  Other than that, I don't have root access to the
% >work machine.
% 
% If you told us which .so file is missing, and which platform you are
% on [you know the rest]. It's probably Motif, in that case you have to
% a Motif implementation, while Lesstif may or may not work as a binary
% plug-in for the real Motif. Ask Peter. You could also compile the CLM
% daemon yourself and link it to Lesstif. You don't need to rebuild
% CMUCL for that.

I am running SuSE 5.3 which shipped with the 2.0.35 kernel.

When I was hitting cons for files, I was grabbing the .tgz files
instead of the .rpm ones.  When I realized I did in fact have RPM, I
used a Perl script called alien to convert my files to .rpm format in
the hope of getting the benefits of the package manager.  When it came
to running RPM on the clm file, RPM complained that I was missing a
.so file that I suspect is related to Motif.  I don't remember the
name.  I'll try to copy it down if I remember when I next boot into
Linux.  I am currently in NT.

For those of you who just arrived, my ISDN card is not supported by
Linux.  I am planing to get an ISDN router to settle that issue.  At
that point, I can set up XEmacs for my news and e-mail.  Maybe I won't
need NT again.

--
David Steuber (ver 1.31.2a)
http://www.david-steuber.com
To reply by e-mail, replace trashcan with david.

"Ignore reality there's nothing you can do about it..."
-- Natalie Imbruglia "Don't you think?"