source: branches/0.22.x/abcl/src/org/armedbear/lisp/threads.lisp

Last change on this file was 12819, checked in by ehuelsmann, 14 years ago

Remove to-be-removed-by-0.22 deprecated symbols, now that we are 0.22.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 4.4 KB
Line 
1;;; threads.lisp
2;;;
3;;; Copyright (C) 2009-2010 Erik Huelsmann <ehuelsmann@common-lisp.net>
4;;;
5;;; $Id: threads.lisp 12819 2010-07-22 18:13:22Z ehuelsmann $
6;;;
7;;; This program is free software; you can redistribute it and/or
8;;; modify it under the terms of the GNU General Public License
9;;; as published by the Free Software Foundation; either version 2
10;;; of the License, or (at your option) any later version.
11;;;
12;;; This program is distributed in the hope that it will be useful,
13;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15;;; GNU General Public License for more details.
16;;;
17;;; You should have received a copy of the GNU General Public License
18;;; along with this program; if not, write to the Free Software
19;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20;;;
21;;; As a special exception, the copyright holders of this library give you
22;;; permission to link this library with independent modules to produce an
23;;; executable, regardless of the license terms of these independent
24;;; modules, and to copy and distribute the resulting executable under
25;;; terms of your choice, provided that you also meet, for each linked
26;;; independent module, the terms and conditions of the license of that
27;;; module.  An independent module is a module which is not derived from
28;;; or based on this library.  If you modify this library, you may extend
29;;; this exception to your version of the library, but you are not
30;;; obligated to do so.  If you do not wish to do so, delete this
31;;; exception statement from your version.
32
33(in-package #:threads)
34
35
36;;
37;; MAKE-THREAD helper to establish restarts
38;;
39
40(defun thread-function-wrapper (fun)
41  (restart-case
42      (funcall fun)
43    (abort () :report "Abort thread.")))
44
45;;
46;; Mailbox implementation
47;;
48
49;; this export statement is also in autoloads.lisp
50(export '(make-mailbox mailbox-send mailbox-empty-p mailbox-read mailbox-peek))
51
52(defstruct mailbox
53  queue)
54
55(defun mailbox-send (mailbox item)
56  "Sends an item into the mailbox, notifying 1 waiter
57to wake up for retrieval of that object."
58  (threads:synchronized-on mailbox
59     (push (mailbox-queue mailbox) item)
60     (threads:object-notify mailbox)))
61
62(defun mailbox-empty-p (mailbox)
63  "Returns non-NIL if the mailbox can be read from, NIL otherwise."
64  ;; Because we're just checking the value of an object reference,
65  ;; (which are atomically gotten and set) we don't need to lock
66  ;; the mailbox before operating on it.
67  (null (mailbox-queue mailbox)))
68
69(defun mailbox-read (mailbox)
70  "Blocks on the mailbox until an item is available for reading.
71When an item is available, it is returned."
72  (threads:synchronized-on mailbox
73     (loop
74        (unless (mailbox-empty-p mailbox)
75          (return))
76        (object-wait mailbox))
77     (pop (mailbox-queue mailbox))))
78
79(defun mailbox-peek (mailbox)
80  "Returns two values. The second returns non-NIL when the mailbox
81is empty. The first is the next item to be read from the mailbox
82if the first is NIL.
83
84Note that due to multi-threading, the first value returned upon
85peek, may be different from the one returned upon next read in the
86calling thread."
87  (threads:synchronized-on mailbox
88     (values (car (mailbox-queue mailbox))
89             (null (mailbox-queue mailbox)))))
90
91
92
93;;
94;; Mutex implementation
95;;
96
97
98;; this export statement is also in autoloads.lisp
99(export '(make-mutex get-mutex release-mutex))
100
101(defstruct mutex
102  in-use)
103
104(defun get-mutex (mutex)
105  "Acquires a lock on the `mutex'."
106  (synchronized-on mutex
107    (loop
108       while (mutex-in-use mutex)
109       do (object-wait mutex))
110    (setf (mutex-in-use mutex) T)))
111
112(defun release-mutex (mutex)
113  "Releases a lock on the `mutex'."
114  (synchronized-on mutex
115    (setf (mutex-in-use mutex) NIL)
116    (object-notify mutex)))
117
118(defmacro with-mutex ((mutex) &body body)
119  "Acquires a lock on `mutex', executes the body
120and releases the lock."
121  (let ((m (gensym)))
122    `(let ((,m ,mutex))
123       (when (get-mutex ,m)
124         (unwind-protect
125          (progn
126            ,@body)
127          (release-mutex ,m))))))
128
129
130;;
131;; Lock implementation
132;;
133
134(defun make-thread-lock ()
135  "Returns an object to be used with the `with-thread-lock' macro."
136  (gensym))
137
138(defmacro with-thread-lock ((lock) &body body)
139  "Acquires a lock on the `lock', executes `body' and releases the lock."
140  (let ((glock (gensym)))
141    `(let ((,glock ,lock))
142       (synchronized-on ,glock
143          ,@body))))
144
Note: See TracBrowser for help on using the repository browser.