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;; present exceptions to this (as distinct from
-current bugs) are:
+current bugs) are:</para>
<itemizedlist>
<listitem><para>the abstract <classname>metaobject</> class is not
present in the class hierarchy;</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.
+ 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.x.y, on Linux x86 only) supports a
+<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.
+system's concept of threads or lightweight processes. </para>
<sect3><title>Lisp-level view</title>
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>
<para>Dynamic bindings to symbols are per-thread. Signal handlers
are per-thread.
+</para>
<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>
<para>Threads arbitrate between themselves for the user's attention.
A thread may be in one of three notional states: foreground,
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>
<para>If the user has multiple views onto the same Lisp image (for
example, using multiple terminals, or a windowing system, or network
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>
<para>Mutexes and condition variables are available for
managing access to shared data: see
-
<itemizedlist>
<listitem>
<programlisting>(apropos "mutex" :sb-thread)</programlisting>
+</listitem>
<listitem>
<programlisting>(apropos "condition" :sb-thread)</programlisting>
+</listitem>
<listitem> <para>and the <structname>waitqueue</structname> structure
</para>
</listitem>
</itemizedlist>
-
-and poke around in their documentation strings.
+and poke around in their documentation strings.</para>
+</sect3>
<sect3><title>Implementation (Linux x86)</title>
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>
<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>
<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>
<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.
+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>
<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.
+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>
<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>
<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
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*
+is managed by locking on <varname>sb-thread::*session-lock*</varname>
+</para>
<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.
+</para>
+
+</sect3>
+
+</sect2>
<sect2><title>Support For Unix</>
one argument is implementation-defined. In &SBCL; it calls functions
on the user-settable list <varname>sb-ext:*module-provider-functions*</varname>
- see the <function>require</function> documentation string for details.
+</para>
<para>The toplevel repl prompt may be customized, and the function
that reads user input may be replaced completely. <!-- FIXME but I
don't currently remember how -->
+</para>
+
+</sect2>
<sect2><title>Tools To Help Developers</title>
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>