Diff of /doc/beyond-ansi.sgml [0ace89] .. [5d4902] Maximize Restore

  Switch to side-by-side view

--- a/doc/beyond-ansi.sgml
+++ b/doc/beyond-ansi.sgml
@@ -1,3 +1,4 @@
+<!-- -*- mode: SGML; sgml-parent-document: ("user-manual.sgml" "BOOK") -*- -->
 <chapter id="beyond-ansi"><title>Beyond The &ANSI; Standard</>
 
 <para>&SBCL; is mostly an implementation of the &ANSI; standard for
@@ -126,6 +127,104 @@
 
 </sect2>
 
+<sect2><title>Threading (a.k.a Multiprocessing)</>
+
+<para>&SBCL; (as of version 0.x.y, on Linux x86 only) supports a
+fairly low-level threading interface that maps onto the host operating
+system's concept of threads or lightweight processes.  
+
+<sect3><title>Lisp-level view</title>
+
+<para>A rudimentary interface to creating and managing multiple threads
+can be found in the <literal>sb-thread</literal> package.  This is
+intended for public consumption, so look at the exported symbols and
+their documentation strings.  
+
+<para>Dynamic bindings to symbols are per-thread.   Signal handlers
+are per-thread.
+
+<para><function>sb-ext:quit</function> exits the current thread, not
+necessarily the whole environment.  The environment will be shut down
+when the last thread exits.
+
+<para>Threads arbitrate between themselves for the user's attention.
+A thread may be in one of three notional states: foreground,
+background, or stopped.  When a background process attempts to print a
+repl prompt or to enter the debugger, it will stop and print a message
+saying that it has stopped.  The user at his leisure may switch to
+that thread to find out what it needs.  If a background thread enters
+the debugger, selecting any restart will put it back into the
+background before it resumes.
+
+<para>If the user has multiple views onto the same Lisp image (for
+example, using multiple terminals, or a windowing system, or network
+access) they are typically set up as multiple `sessions' such that each 
+view has its own collection of foreground/background/stopped threads.
+<function>sb-thread:make-listener-thread</function> can be used to
+start a new thread in its own `session'.
+
+<para>A small selection of locking primitives are available for
+managing access to shared data: see <programlisting>(apropos "mutex"
+:sb-thread)</programlisting> and the documentation strings for the
+functions it lists.
+
+<sect3><title>Implementation (Linux x86)</title>
+
+<para>On Linux x86, this is implemented using
+<function>clone()</function> and does not involve pthreads.  This is
+not because there is anything wrong with pthreads <emphasis>per
+se</emphasis>, but there is plenty wrong (from our perspective) with
+LinuxThreads.  &SBCL; threads are mapped 1:1 onto Linux tasks which
+share a VM but nothing else - each has its own process id and can be
+seen in e.g. <command>ps</command> output.
+
+<para>Per-thread local bindings for special variables is achieved
+using the %gs segment register to point to a per-thread storage area.
+This may cause interesting results if you link to foreign code that
+expects threading or creates new threads, and the thread library in
+question uses %gs in an incompatible way.
+
+<para>Threads waiting for locks are put to sleep using
+<function>sigtimedwait()</function> and woken with SIGALRM.  
+
+<para>&SBCL; at present will alway have at least two tasks running as
+seen from Linux: when the first process has done startup
+initialization (mapping files in place, installing signal handlers
+etc) it creates a new thread to run the Lisp startup and initial listener.
+The original thread is then used to run GC and to reap dead subthreads
+when they exit.
+
+<para>Garbage collection is done with the existing Conservative
+Generational GC.  Allocation is done in small (typically 8k) regions :
+each thread has its own region so this involves no stopping. However,
+when a region fills, a lock must be obtained while another is
+allocated, and when a collection is required, all processes are
+stopped.  This is achieved using <function>ptrace()</function>, so you
+should be very careful if you wish to examine an &SBCL; worker thread
+using <command>strace</command>, <command>truss</command>,
+<command>gdb</command> or similar.  It may be prudent to disable GC
+before doing so.
+
+<para>Large amounts of the &SBCL; library have not been inspected for
+thread-safety.  Some of the obviously unsafe areas have large locks
+around them, so compilation and fasl loading, for example, cannot be
+parallelized.  Work is ongoing in this area.
+
+<para>A new thread by default is created in the same POSIX process
+group and session as the thread it was created by.  This has an impact
+on keyboard interrupt handling: pressing your terminal's intr key
+(typically Control-C) will interrupt all processes in the foreground
+process group, including Lisp threads that &SBCL; considers to be
+notionally `background'.  This is undesirable, so background threads
+are set to ignore the SIGINT signal.  Arbitration for the input stream
+is managed by locking on sb-thread::*session-lock*
+
+<para>A thread can be created in a new Lisp 'session' (new terminal or
+window) using <function>sb-thread:make-listener-thread</function>.
+These sessions map directly onto POSIX sessions, so that pressing
+Control-C in the wrong window will not interrupt them - this has been
+found to often be embarrassing.
+
 <sect2><title>Support For Unix</>
 
 <para>The UNIX command line can be read from the variable
@@ -235,4 +334,4 @@
 
 </sect1>
 
-</chapter>+</chapter>