1.0.41.42: ppc: Documentation and NEWS updates for threading.
[sbcl.git] / doc / manual / threading.texinfo
index 6efed89..b51ba34 100644 (file)
 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 
+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.
 
-This requires x86 and Linux kernel 2.6 or systems with NPTL backports.
+Threads are part of the default build on x86[-64] Linux only.
+
+They are also experimentally supported on: x86[-64] Darwin (Mac OS X),
+x86[-64] FreeBSD, x86 SunOS (Solaris), and PPC Linux. On these platforms
+threads must be explicitly enabled at build-time, see @file{INSTALL} for
+directions.
 
 @menu
+* Threading basics::            
 * Special Variables::           
+* Atomic Operations::           
 * Mutex Support::               
+* Semaphores::                  
 * Waitqueue/condition variables::  
+* Barriers::                    
 * Sessions/Debugging::          
-* Implementation (Linux x86)::  
+* Foreign threads::             
+* Implementation (Linux x86/x86-64)::  
 @end menu
 
+@node Threading basics
+@comment  node-name,  next,  previous,  up
+@section Threading basics
+
+@lisp
+(make-thread (lambda () (write-line "Hello, world")))
+@end lisp
+
+@subsection Thread Objects
+
+@include struct-sb-thread-thread.texinfo
+@include var-sb-thread-star-current-thread-star.texinfo
+@include fun-sb-thread-list-all-threads.texinfo
+@include fun-sb-thread-thread-alive-p.texinfo
+@include fun-sb-thread-thread-name.texinfo
+
+@subsection Making, Joining, and Yielding Threads
+
+@include fun-sb-thread-make-thread.texinfo
+@include fun-sb-thread-thread-yield.texinfo
+@include fun-sb-thread-join-thread.texinfo
+
+@subsection Asynchronous Operations
+
+@include fun-sb-thread-interrupt-thread.texinfo
+@include fun-sb-thread-terminate-thread.texinfo
+
+@subsection Miscellaneous Operations
+
+@include fun-sb-thread-symbol-value-in-thread.texinfo
+
+@subsection Error Conditions
+
+@include condition-sb-thread-thread-error.texinfo
+@include fun-sb-thread-thread-error-thread.texinfo
+
+@c @include condition-sb-thread-symbol-value-in-thread-error.texinfo
+@include condition-sb-thread-interrupt-thread-error.texinfo
+@include condition-sb-thread-join-thread-error.texinfo
+
 @node Special Variables
 @comment  node-name,  next,  previous,  up
 @section Special Variables
 
 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.
+as one would expect, with behaviour very similar to other
+implementations.
 
 @itemize
-@item 
+@item
 global special values are visible across all threads;
 @item
 bindings (e.g. using LET) are local to the thread;
 @item
-initial values in a new thread are taken from the thread that created it. 
+threads do not inherit dynamic bindings from the parent thread
 @end itemize
 
+The last point means that
+
+@lisp
+(defparameter *x* 0)
+(let ((*x* 1))
+  (sb-thread:make-thread (lambda () (print *x*))))
+@end lisp
+
+prints @code{0} and not @code{1} as of 0.9.6.
+
+@node Atomic Operations
+@comment  node-name,  next,  previous,  up
+@section Atomic Operations
+
+SBCL provides a few special purpose atomic operations, particularly
+useful for implementing lockless algorithms.
+
+@include macro-sb-ext-atomic-decf.texinfo
+@include macro-sb-ext-atomic-incf.texinfo
+@include macro-sb-ext-compare-and-swap.texinfo
+
 @node Mutex Support
 @comment  node-name,  next,  previous,  up
 @section Mutex Support
@@ -58,18 +128,40 @@ if you want a bounded wait.
 (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)))
+  (format t "Thread ~A running ~%" *current-thread*)
+  (with-mutex (*a-mutex*)
+    (format t "Thread ~A got the lock~%" *current-thread*)
+    (sleep (random 5)))
+  (format t "Thread ~A dropped lock, dying now~%" *current-thread*))
 
 (make-thread #'thread-fn)
 (make-thread #'thread-fn)
-
 @end lisp
 
+@include struct-sb-thread-mutex.texinfo
+@include fun-sb-thread-make-mutex.texinfo
+@include fun-sb-thread-mutex-name.texinfo
+@include fun-sb-thread-mutex-value.texinfo
+@include fun-sb-thread-get-mutex.texinfo
+@include fun-sb-thread-release-mutex.texinfo
+@include macro-sb-thread-with-mutex.texinfo
+@include macro-sb-thread-with-recursive-lock.texinfo
+
+@node Semaphores
+@comment  node-name,  next,  previous,  up
+@section Semaphores
+
+described here should be considered
+experimental, subject to API changes without notice.
+
+@include struct-sb-thread-semaphore.texinfo
+@include fun-sb-thread-make-semaphore.texinfo
+@include fun-sb-thread-semaphore-count.texinfo
+@include fun-sb-thread-semaphore-name.texinfo
+@include fun-sb-thread-signal-semaphore.texinfo
+@include fun-sb-thread-try-semaphore.texinfo
+@include fun-sb-thread-wait-on-semaphore.texinfo
+
 @node Waitqueue/condition variables
 @comment  node-name,  next,  previous,  up
 @section Waitqueue/condition variables
@@ -85,29 +177,29 @@ when you weren't expecting it to.
 There are three components:
 
 @itemize
-@item 
+@item
 the condition itself (not represented in code)
 
-@item 
+@item
 the condition variable (a.k.a waitqueue) which proxies for it
 
-@item 
-a lock to hold while testing the condition 
+@item
+a lock to hold while testing the condition
 @end itemize
 
 Important stuff to be aware of:
 
 @itemize
-@item 
+@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;
 
-@item 
+@item
 likewise, you must be holding the mutex around calls to
 condition-notify;
 
-@item 
+@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
@@ -129,25 +221,61 @@ it.
       (unless *buffer* (return))
       (let ((head (car *buffer*)))
         (setf *buffer* (cdr *buffer*))
-        (format t "reader ~A woke, read ~A~%" 
-                (current-thread-id) head))))))
+        (format t "reader ~A woke, read ~A~%"
+                *current-thread* head))))))
 
 (defun writer ()
   (loop
    (sleep (random 5))
    (with-mutex (*buffer-lock*)
      (let ((el (intern
-                (string (code-char 
+                (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)       
-
+(make-thread #'reader)
 @end lisp
 
+@include struct-sb-thread-waitqueue.texinfo
+@include fun-sb-thread-make-waitqueue.texinfo
+@include fun-sb-thread-waitqueue-name.texinfo
+@include fun-sb-thread-condition-wait.texinfo
+@include fun-sb-thread-condition-notify.texinfo
+@include fun-sb-thread-condition-broadcast.texinfo
+
+@node Barriers
+@comment  node-name,  next,  previous,  up
+@section Barriers
+
+These are based on the Linux kernel barrier design, which is in turn
+based on the Alpha CPU memory model.  They are presently implemented for
+x86, x86-64, and PPC systems, and behave as compiler barriers on all
+other CPUs.
+
+In addition to explicit use of the @code{sb-thread:barrier} macro, the
+following functions and macros also serve as @code{:memory} barriers:
+
+@itemize
+@item
+@code{sb-ext:atomic-decf} and @code{sb-ext:atomic-incf}.
+@item
+@code{sb-ext:compare-and-swap}.
+@item
+@code{sb-thread:get-mutex}, @code{sb-thread:release-mutex},
+@code{sb-thread:with-mutex} and @code{sb-thread:with-recursive-lock}.
+@item
+@code{sb-thread:signal-semaphore}, @code{sb-thread:try-semaphore} and
+@code{sb-thread:wait-on-semaphore}.
+@item
+@code{sb-thread:condition-wait}, @code{sb-thread:condition-notify} and
+@code{sb-thread:condition-broadcast}.
+@end itemize
+
+@include macro-sb-thread-barrier.texinfo
+
 @node Sessions/Debugging
 @comment  node-name,  next,  previous,  up
 @section Sessions/Debugging
@@ -159,7 +287,7 @@ 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.  
+fresh one.
 # See also @code{sb-thread:make-listener-thread}.
 
 Within a single session, threads arbitrate between themselves for the
@@ -176,22 +304,40 @@ input stream is managed by calls to @code{sb-thread:get-foreground}
 @code{sb-ext:quit} terminates all threads in the current session, but
 leaves other sessions running.
 
-@node Implementation (Linux x86)
+@node Foreign threads
 @comment  node-name,  next,  previous,  up
-@section Implementation (Linux x86)
-
-On Linux x86, threading is implemented using @code{clone()} and does
-not involve pthreads.  This is not because there is anything wrong
-with pthreads @emph{per se}, 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} output.
-
-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.
+@section Foreign threads
+
+Direct calls to @code{pthread_create} (instead of @code{MAKE-THREAD})
+create threads that SBCL is not aware of, these are called foreign
+threads. Currently, it is not possible to run Lisp code in such
+threads. This means that the Lisp side signal handlers cannot work.
+The best solution is to start foreign threads with signals blocked,
+but since third party libraries may create threads, it is not always
+feasible to do so. As a workaround, upon receiving a signal in a
+foreign thread, SBCL changes the thread's sigmask to block all signals
+that it wants to handle and resends the signal to the current process
+which should land in a thread that does not block it, that is, a Lisp
+thread.
+
+The resignalling trick cannot work for synchronously triggered signals
+(SIGSEGV and co), take care not to trigger any. Resignalling for
+synchronously triggered signals in foreign threads is subject to
+@code{--lose-on-corruption}, see @ref{Runtime Options}.
+
+@node Implementation (Linux x86/x86-64)
+@comment  node-name,  next,  previous,  up
+@section Implementation (Linux x86/x86-64)
+
+Threading is implemented using pthreads and some Linux specific bits
+like futexes.
+
+On x86 the 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. On x86-64 the r12 register
+has a similar role.
 
 Queues require the @code{sys_futex()} system call to be available:
 this is the reason for the NPTL requirement.  We test at runtime that