+<!-- -*- 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
is <function>eql</> to the old value. Conforming to this specification
is a nuisance when the "constant" value is only constant under some
weaker test like <function>string=</> or <function>equal</>. It's
-especially annoying because <function>defconstant</> takes effect
+especially annoying because, in &SBCL;, <function>defconstant</> takes effect
not only at load time but also at compile time, so that just
compiling and loading reasonable code like
<programlisting>(defconstant +foobyte+ '(1 4))</>
<function>defconstant</> either with <function>defparameter</> or
with a customized macro which does the right thing, possibly along the
lines of the <function>defconstant-eqx</> macro used internally in the
-implementation of SBCL itself.</para>
+implementation of &SBCL; itself. In circumstances where this is not
+appropriate, the programmer can handle the condition type
+<errortype>sb-ext:defconstant-uneql</errortype>, and choose either the
+<action>continue</action> or <action>abort</action> restart as
+appropriate.</para>
<para>&SBCL; gives style warnings about various kinds of perfectly
legal code, e.g.
<para>&SBCL; provides additional garbage collection functionality not
specified by &ANSI;. Weak pointers allow references to objects to be
maintained without keeping them from being GCed. And "finalization"
-hooks are available to cause code to be executed when an object is
+hooks are available to cause code to be executed when an object has been
GCed.</para> <!-- FIXME: Actually documenting these would be good.:-| -->
<para>&SBCL; supports Gray streams, user-overloadable CLOS classes
whose instances can be used as Lisp streams (e.g. passed as the
-first argument to <function>format</>).</para>
+first argument to <function>format</>). Additionally, the
+bundled contrib module <interface>sb-simple-streams</interface>
+implements a subset of the Franz Allegro simple-streams proposal.</para>
<para>&SBCL; supports a MetaObject Protocol which is intended to be
-compatible with &AMOP;; exceptions to this (as distinct from current
-bugs<!-- Such as the distinction between CL:FIND-CLASS and
-SB-PCL::FIND-CLASS :-( -->) are that
-<function>compute-effective-method</> only returns one value, not
-two<!-- FIXME: anything else? What about extensions? (e.g. COMPUTE-SLOTS
-behaviour) -->.</para>
+compatible with &AMOP;; present exceptions to this (as distinct from
+current bugs) are:</para>
+<itemizedlist>
+ <listitem><para>the abstract <classname>metaobject</> class is not
+ present in the class hierarchy;</para></listitem>
+ <listitem><para>the <classname>standard-object</> and
+ <classname>funcallable-standard-object</> classes are
+ disjoint;</para></listitem>
+ <listitem><para><function>compute-effective-method</> only returns
+ one value, not two;</para></listitem>
+ <listitem><para>the system-supplied <property>:around</> method for
+ <function>compute-slots</> specialized on
+ <classname>funcallable-standard-class</> does not respect the
+ requested order from a user-supplied primary method.</para>
+</listitem>
+</itemizedlist>
</sect2>
+<sect2><title>Threading (a.k.a Multiprocessing)</>
+
+<para>&SBCL; (as of version 0.8.3, 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. </para>
+
+<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>Mutexes and condition variables are available for
+managing access to shared data: see
+
+<itemizedlist>
+<listitem>
+<programlisting>(apropos "mutex" :sb-thread)</programlisting>
+<listitem>
+<programlisting>(apropos "condition" :sb-thread)</programlisting>
+<listitem> <para>and the <structname>waitqueue</structname> structure
+</para>
+</listitem>
+</itemizedlist>
+
+and poke around in their documentation strings.
+
+<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 %fs 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 %fs in an incompatible way.
+
+<para>Threads waiting on queues (e.g. for locks or condition
+variables) are put to sleep using <function>sigtimedwait()</function>
+and woken with SIGCONT.
+
+<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 stays around to reap dead subthreads
+and deallocate their resources (e.g. stacks) 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 by sending them signals, which may make for
+interesting behaviour if they are interrupted in system calls. The
+streams interface is believed to handle the required system call
+restarting correctly, but this may be a consideration when making
+other blocking calls e.g. from foreign library code.
+
+<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 <varname>sb-thread::*session-lock*</varname>
+
+<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 be embarrassing.
+
<sect2><title>Support For Unix</>
<para>The UNIX command line can be read from the variable
between multiple Lisp processes. is less important with modern
generational garbage collectors. </para>
-<para>The <function>sb-ext:truly-the</> operator does what the
-<function>cl:the</> operator does in a more conventional
-implementation of &CommonLisp;, declaring the type of its argument
-without any runtime checks. (Ordinarily in &SBCL;, any type
-declaration is treated as an assertion and checked at runtime.)</para>
+<para>The <function>sb-ext:truly-the</> declares the type of the
+result of the operations, producing its argument; the declaration is
+not checked. In short: don't use it.</para>
<para>The <function>sb-ext:freeze-type</> declaration declares that a
type will never change, which can make type testing
is <emphasis>not</> appropriate for functions like <function>aref</>,
which can change their return values when the underlying data are
changed.</para>
+<!-- FIXME: This declaration does not seem to be supported in the --
+ -- current compiler. -->
</sect2>
</sect1>
-</chapter>
\ No newline at end of file
+</chapter>