0.8.13.70: MORE DOCUMENTATION
[sbcl.git] / doc / manual / beyond-ansi.texinfo
index 82d824f..848fb48 100644 (file)
@@ -1,7 +1,3 @@
-@node  Beyond The ANSI Standard
-@comment  node-name,  next,  previous,  up
-@chapter Beyond The ANSI Standard
-
 SBCL is mostly an implementation of the ANSI standard for
 Common Lisp. However, there's some important behavior which extends
 or clarifies the standard, and various behavior which outright
@@ -23,8 +19,8 @@ exceptions involve internal inconsistencies in the standard.)  In SBCL
 0.7.6, the master record of known bugs is in the @file{BUGS} file in
 the distribution.  Some highlight information about bugs may also be
 found in the manual page. The recommended way to report bugs is
-through the sbcl-help or sbcl-devel mailings lists.  For mailing list
-addresses, @ref{More SBCL Information}.
+through the sbcl-help or sbcl-devel mailing lists.  For mailing list
+addresses, @xref{More SBCL Information}.
 
 
 @node Idiosyncrasies
@@ -37,8 +33,8 @@ implementation.
 
 Declarations are generally treated as assertions. This general
 principle, and its implications, and the bugs which still keep the
-compiler from quite satisfying this principle, are discussed in the
-chapter on the compiler, @ref{The Compiler}.
+compiler from quite satisfying this principle, are discussed in
+@ref{Compiler}.
 
 SBCL is essentially a compiler-only implementation of Common
 Lisp. That is, for all but a few special cases, @code{eval} creates a
@@ -48,6 +44,7 @@ resulting function object. This is explicitly allowed by the ANSI
 standard, but leads to some oddities, e.g. collapsing @code{functionp}
 and @code{compiled-function-p} into the same predicate.
 
+@findex defconstant
 SBCL is quite strict about ANSI's definition of
 @code{defconstant}. ANSI says that doing @code{defconstant} of the
 same symbol more than once is undefined unless the new value is
@@ -57,11 +54,9 @@ weaker test like @code{string=} or @code{equal}. It's especially
 annoying because, in SBCL, @code{defconstant} takes effect not only at
 load time but also at compile time, so that just compiling and loading
 reasonable code like
-
 @lisp
 (defconstant +foobyte+ '(1 4))
 @end lisp
-
 runs into this undefined behavior. Many implementations of Common Lisp
 try to help the programmer around this annoyance by silently accepting
 the undefined code and trying to do what the programmer probably
@@ -82,10 +77,10 @@ e.g.
 @itemize
   
 @item
-@code{defmethod} without @code{defgeneric}
+@code{defmethod} without a preceding @code{defgeneric};
   
 @item
-multiple @code{defun}s of the same symbol
+multiple @code{defun}s of the same symbol in different units;
   
 @item
 special variables not named in the conventional @code{*foo*} style,
@@ -113,7 +108,7 @@ case, but still isn't as of SBCL 0.7.6.)
 
 SBCL is derived from CMUCL, which implements many extensions to the
 ANSI standard. SBCL doesn't support as many extensions as CMUCL, but
-it still has quite a few.
+it still has quite a few.  @xref{Contributed Modules}.
 
 
 @menu
@@ -131,8 +126,8 @@ it still has quite a few.
 @comment  node-name,  next,  previous,  up
 @subsection Things Which Might Be In The Next ANSI Standard
 
-SBCL provides extensive support for calling external C code, @ref{The
-Foreign Function Interface}.
+SBCL provides extensive support for calling external C code,
+@ref{Foreign Function Interface}.
 
 SBCL provides additional garbage collection functionality not
 specified by ANSI. Weak pointers allow references to objects to be
@@ -176,39 +171,125 @@ requested order from a user-supplied primary method.
 @comment  node-name,  next,  previous,  up
 @subsection Threading (a.k.a Multiprocessing)
 
-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.
-
-@subsubsection Lisp-level view
+SBCL supports a fairly low-level threading interface that maps onto
+the host operating system's concept of threads or lightweight
+processes.  This means that threads may take advantage of hardware
+multiprocessing on machines that have more than one CPU, but it does 
+not allow Lisp control of the scheduler.  This is found in the
+SB-THREAD package.
 
-A rudimentary interface to creating and managing multiple threads can
-be found in the @dfn{sb-thread} package.  This is intended for public
-consumption, so look at the exported symbols and their documentation
-strings.
+This requires x86 and Linux kernel 2.6 or systems with NPTL backports.
 
-Dynamic bindings to symbols are per-thread.  Signal handlers are
-per-thread.
+@subsubsection Special variables
 
-Mutexes and condition variables are available for managing access to
-shared data: see
+The interaction of special variables with multiple threads is mostly
+as one would expect, but users of other Lisps are warned that the
+behaviour of locally bound specials differs in places from what they
+may expect.
 
 @itemize
-
+@item 
+global special values are visible across all threads;
 @item
-@code{(apropos "mutex" :sb-thread)}
-  
+bindings (e.g. using LET) are local to the thread;
 @item
-@code{(apropos "condition" :sb-thread)}
-  
-@item
-and the @code{waitqueue} structure
+initial values in a new thread are taken from the thread that created it. 
+@end itemize
+
+@subsubsection Mutex support
+
+Mutexes are used for controlling access to a shared resource. One
+thread is allowed to hold the mutex, others which attempt to take it
+will be made to wait until it's free. Threads are woken in the order
+that they go to sleep.
+
+There isn't a timeout on mutex acquisition, but the usual WITH-TIMEOUT
+macro (which throws a TIMEOUT condition after n seconds) can be used
+if you want a bounded wait.
+
+@lisp
+(defpackage :demo (:use "CL" "SB-THREAD" "SB-EXT"))
+
+(in-package :demo)
+
+(defvar *a-mutex* (make-mutex :name "my lock"))
+
+(defun thread-fn ()
+  (let ((id (current-thread-id)))
+    (format t "Thread ~A running ~%" id)
+    (with-mutex (*a-mutex*)
+      (format t "Thread ~A got the lock~%" id)
+      (sleep (random 5)))
+    (format t "Thread ~A dropped lock, dying now~%" id)))
+
+(make-thread #'thread-fn)
+(make-thread #'thread-fn)
 
+@end lisp
+
+@subsubsection Waitqueue/condition variables
+
+These are based on the POSIX condition variable design, hence the
+annoyingly CL-conflicting name. For use when you want to check a
+condition and sleep until it's true. For example: you have a shared
+queue, a writer process checking ``queue is empty'' and one or more
+readers that need to know when ``queue is not empty''. It sounds
+simple, but is astonishingly easy to deadlock if another process runs
+when you weren't expecting it to.
+
+There are three components:
+
+@itemize
+@item the condition itself (not represented in code)
+@item the condition variable (a.k.a waitqueue) which proxies for it
+@item a lock to hold while testing the condition 
 @end itemize
 
-and poke around in their documentation strings.
+Important stuff to be aware of:
+
+@itemize
+@item when calling condition-wait, you must hold the mutex. condition-wait will drop the mutex while it waits, and obtain it again before returning for whatever reason;
 
-@subsubsection Sessions
+@item likewise, you must be holding the mutex around calls to condition-notify;
+
+@item a process may return from condition-wait in several circumstances: it is not guaranteed that the underlying condition has become true. You must check that the resource is ready for whatever you want to do to it. 
+
+@end itemize
+
+@lisp
+(defvar *buffer-queue* (make-waitqueue))
+(defvar *buffer-lock* (make-mutex :name "buffer lock"))
+
+(defvar *buffer* (list nil))
+
+(defun reader ()
+  (with-mutex (*buffer-lock*)
+    (loop
+     (condition-wait *buffer-queue* *buffer-lock*)
+     (loop
+      (unless *buffer* (return))
+      (let ((head (car *buffer*)))
+        (setf *buffer* (cdr *buffer*))
+        (format t "reader ~A woke, read ~A~%" 
+                (current-thread-id) head))))))
+
+(defun writer ()
+  (loop
+   (sleep (random 5))
+   (with-mutex (*buffer-lock*)
+     (let ((el (intern
+                (string (code-char 
+                         (+ (char-code #\A) (random 26)))))))
+       (setf *buffer* (cons el *buffer*)))
+     (condition-notify *buffer-queue*))))
+
+(make-thread #'writer)
+(make-thread #'reader)
+(make-thread #'reader)       
+
+@end lisp
+
+@subsubsection Sessions/Debugging
 
 If the user has multiple views onto the same Lisp image (for example,
 using multiple terminals, or a windowing system, or network access)
@@ -217,7 +298,8 @@ view has its own collection of foreground/background/stopped threads.
 A thread which wishes to create a new session can use
 @code{sb-thread:with-new-session} to remove itself from the current
 session (which it shares with its parent and siblings) and create a
-fresh one.  See also @code{sb-thread:make-listener-thread}.
+fresh one.  
+# See also @code{sb-thread:make-listener-thread}.
 
 Within a single session, threads arbitrate between themselves for the
 user's attention.  A thread may be in one of three notional states:
@@ -249,13 +331,9 @@ 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.
 
-There are two implementation mechanisms for queueing.  If SBCL was
-built on an NPTL-capable Linux system (2.6 or some vendor 2.4 ports)
-with the @code{:SB-FUTEX} feature, queuing will be done using the
-@code{sys_futex()} system call if it's available at runtime.
-Otherwise it will fall back to using @code{sigtimedwait()} to sleep
-and a signal (@code{SIG_DEQUEUE}, one of the POSIX RT signals) to
-wake.
+Queues require the @code{sys_futex()} system call to be available:
+this is the reason for the NPTL requirement.  We test at runtime that
+this system call exists.
 
 Garbage collection is done with the existing Conservative Generational
 GC.  Allocation is done in small (typically 8k) regions: each thread
@@ -318,9 +396,14 @@ implementation-defined.  In SBCL, @code{require} behaves in the
 following way:
 
 @include fun-common-lisp-require.texinfo
-
 @include var-sb-ext-star-module-provider-functions-star.texinfo
 
+Although SBCL does not provide a resident editor, the @code{ed}
+function can be customized to hook into user-provided editing
+mechanisms as follows:
+
+@include fun-common-lisp-ed.texinfo
+@include var-sb-ext-star-ed-functions-star.texinfo
 
 @node  Tools To Help Developers
 @comment  node-name,  next,  previous,  up
@@ -330,13 +413,11 @@ SBCL provides a profiler and other extensions to the ANSI @code{trace}
 facility.  For more information, see @ref{macro-common-lisp-trace}.
 
 The debugger supports a number of options. Its documentation is
-accessed by typing @kbd{help} at the debugger prompt.  @xref{The
-Debugger}.
+accessed by typing @kbd{help} at the debugger prompt. @xref{Debugger}.
 
 Documentation for @code{inspect} is accessed by typing @kbd{help} at
 the @code{inspect} prompt.
 
-
 @node  Interface To Low-Level SBCL Implementation
 @comment  node-name,  next,  previous,  up
 @subsection Interface To Low-Level SBCL Implementation
@@ -344,12 +425,13 @@ the @code{inspect} prompt.
 SBCL has the ability to save its state as a file for later
 execution. This functionality is important for its bootstrapping
 process, and is also provided as an extension to the user.  Note that
-foreign libraries loaded via @code{load-1-foreign} don't survive this
-process; a core should not be saved in this case.
+foreign libraries loaded via @code{load-shared-object} don't survive
+this process; a core should not be saved in this case.
 
 @emph{FIXME: what should be done for foreign libraries?}
 
-@emph{FIXME: document load-1-foreign somewhere}
+@emph{FIXME: document load-shared-object somewhere - it's in
+ffi.texinfo?}
 
 @include fun-sb-ext-save-lisp-and-die.texinfo
 
@@ -393,9 +475,9 @@ generational garbage collectors.
 
 @include fun-sb-ext-purify.texinfo
 
-@code{sb-ext:truly-the} special form declares the type of the result
-of the operations, producing its argument; the declaration is not
-checked. In short: don't use it.
+The @code{sb-ext:truly-the} special form declares the type of the
+result of the operations, producing its argument; the declaration is
+not checked. In short: don't use it.
 
 @include special-operator-sb-ext-truly-the.texinfo