Add THREAD-JOIN interface and the implementation for SBCL.
[bordeaux-threads.git] / src / bordeaux-threads.lisp
blobe435b4d04c5b38d2f22a5486cf5b5380c30debb1
1 #|
2 Copyright 2006, 2007 Greg Pfeil
4 Distributed under the MIT license (see LICENSE file)
5 |#
7 (defpackage bordeaux-threads
8 (:nicknames #:bt #:threads)
9 (:documentation "BORDEAUX-THREADS is a proposed standard for a minimal
10 MP/threading interface. It is similar to the CLIM-SYS threading and
11 lock support, but for the following broad differences:
13 1) Some behaviours are defined in additional detail: attention has
14 been given to special variable interaction, whether and when
15 cleanup forms are run. Some behaviours are defined in less
16 detail: an implementation that does not support multiple
17 threads is not required to use a new list (nil) for a lock, for
18 example.
20 2) Many functions which would be difficult, dangerous or inefficient
21 to provide on some implementations have been removed. Chiefly
22 these are functions such as thread-wait which expect for
23 efficiency that the thread scheduler is written in Lisp and
24 'hookable', which can't sensibly be done if the scheduler is
25 external to the Lisp image, or the system has more than one CPU.
27 3) Unbalanced ACQUIRE-LOCK and RELEASE-LOCK functions have been
28 added.
30 4) Posix-style condition variables have been added, as it's not
31 otherwise possible to implement them correctly using the other
32 operations that are specified.
34 Threads may be implemented using whatever applicable techniques are
35 provided by the operating system: user-space scheduling,
36 kernel-based LWPs or anything else that does the job.
38 Some parts of this specification can also be implemented in a Lisp
39 that does not support multiple threads. Thread creation and some
40 thread inspection operations will not work, but the locking
41 functions are still present (though they may do nothing) so that
42 thread-safe code can be compiled on both multithread and
43 single-thread implementations without need of conditionals.
45 To avoid conflict with existing MP/threading interfaces in
46 implementations, these symbols live in the BORDEAUX-THREADS package.
47 Implementations and/or users may also make them visible or exported
48 in other more traditionally named packages.")
49 (:use #:cl)
50 (:export #:make-thread #:current-thread #:threadp #:thread-name
51 #:*default-special-bindings* #:*supports-threads-p*
53 #:make-lock #:acquire-lock #:release-lock #:with-lock-held
54 #:make-recursive-lock #:acquire-recursive-lock
55 #:release-recursive-lock #:with-recursive-lock-held
57 #:make-condition-variable #:condition-wait #:condition-notify
58 #:thread-yield
60 #:with-timeout #:timeout
62 #:all-threads #:interrupt-thread #:destroy-thread #:thread-alive-p
63 #:join-thread))
65 (in-package #:bordeaux-threads)
67 (defvar *supports-threads-p* nil
68 "This should be set to T if the running instance has thread support.")
70 (defun mark-supported ()
71 (setf *supports-threads-p* t)
72 (pushnew :bordeaux-threads *features*))
74 (define-condition bordeaux-mp-condition (error)
75 ((message :initarg :message :reader message))
76 (:report (lambda (condition stream)
77 (format stream (message condition)))))
79 (defgeneric make-threading-support-error ()
80 (:documentation "Creates a BORDEAUX-THREADS condition which specifies
81 whether there is no BORDEAUX-THREADS support for the implementation, no
82 threads enabled for the system, or no support for a particular
83 function.")
84 (:method ()
85 (make-condition
86 'bordeaux-mp-condition
87 :message (if *supports-threads-p*
88 "There is no support for this method on this implementation."
89 "There is no thread support in this instance."))))
91 (define-condition timeout (serious-condition) ())
93 ;;; Thread Creation
95 ;;; See default-implementations.lisp for MAKE-THREAD.
97 (defvar *default-special-bindings* '()
98 "This variable holds an alist associating special variable symbols
99 with forms to evaluate for binding values. Special variables named
100 in this list will be locally bound in the new thread before it
101 begins executing user code.
103 This variable may be rebound around calls to MAKE-THREAD to
104 add/alter default bindings. The effect of mutating this list is
105 undefined, but earlier forms take precedence over later forms for
106 the same symbol, so defaults may be overridden by consing to the
107 head of the list."
108 ;; Forms are evaluated in the new thread or in the calling thread?
109 ;; Standard contents of this list: print/reader control, etc. Can
110 ;; borrow the franz equivalent?
113 ;;; FIXME: This test won't work if CURRENT-THREAD
114 ;;; conses a new object each time
115 (defun signal-error-if-current-thread (thread)
116 (when (eq thread (current-thread))
117 (error
118 (make-condition 'bordeaux-mp-condition
119 :message "Can not destroy the current thread"))))