[slime-cvs] CVS slime
CVS User mevenson
mevenson at common-lisp.net
Tue Aug 18 10:42:08 UTC 2009
Update of /project/slime/cvsroot/slime
In directory cl-net:/tmp/cvs-serv22838
Modified Files:
ChangeLog swank-abcl.lisp
Log Message:
Add multithreading code for abcl-0.16. (Tobias Rittweiler)
* swank-abcl.lisp: A multithread implementation taking advantage
of the new synchronization primitives in abcl-0.16.
--- /project/slime/cvsroot/slime/ChangeLog 2009/08/18 09:51:12 1.1840
+++ /project/slime/cvsroot/slime/ChangeLog 2009/08/18 10:42:07 1.1841
@@ -1,5 +1,10 @@
2009-08-18 Mark Evenson <evenson at panix.com>
+ Add multithreading code for abcl-0.16. (Tobias Rittweiler)
+
+ * swank-abcl.lisp: A multithread implementation taking advantage
+ of the new synchronization primitives in abcl-0.16.
+
Restore working with abcl-0.15.
* swank-abcl.lisp: Remove the warm initialization code for
--- /project/slime/cvsroot/slime/swank-abcl.lisp 2009/08/18 09:51:12 1.66
+++ /project/slime/cvsroot/slime/swank-abcl.lisp 2009/08/18 10:42:07 1.67
@@ -119,7 +119,11 @@
(defimplementation preferred-communication-style ()
- nil)
+#+#.(cl:if (cl:find-package :threads) '(:and) '(:or))
+ :spawn
+#-#.(cl:if (cl:find-package :threads) '(:and) '(:or))
+ nil
+)
(defimplementation create-socket (host port)
(ext:make-server-socket port))
@@ -483,87 +487,97 @@
;;;; Multithreading
-(defimplementation startup-multiprocessing ()
- #+nil(mp:start-scheduler))
-
-(defimplementation spawn (fn &key name)
- (ext:make-thread (lambda () (funcall fn)) :name name))
-
-(defvar *thread-props-lock* (ext:make-thread-lock))
-
-(defvar *thread-props* (make-hash-table) ; should be a weak table
- "A hashtable mapping threads to a plist.")
-
-(defvar *thread-id-counter* 0)
-
-(defimplementation thread-id (thread)
- (ext:with-thread-lock (*thread-props-lock*)
- (or (getf (gethash thread *thread-props*) 'id)
- (setf (getf (gethash thread *thread-props*) 'id)
+#+#.(cl:if (cl:find-package :threads) '(:and) '(:or))
+(progn
+ (defimplementation spawn (fn &key name)
+ (threads:make-thread (lambda () (funcall fn)) :name name))
+
+ (defvar *thread-plists* (make-hash-table) ; should be a weak table
+ "A hashtable mapping threads to a plist.")
+
+ (defvar *thread-id-counter* 0)
+
+ (defimplementation thread-id (thread)
+ (threads:synchronized-on *thread-plists*
+ (or (getf (gethash thread *thread-plists*) 'id)
+ (setf (getf (gethash thread *thread-plists*) 'id)
(incf *thread-id-counter*)))))
-(defimplementation find-thread (id)
- (find id (all-threads)
+ (defimplementation find-thread (id)
+ (find id (all-threads)
:key (lambda (thread)
- (getf (gethash thread *thread-props*) 'id))))
+ (getf (gethash thread *thread-plists*) 'id))))
-(defimplementation thread-name (thread)
- (ext:thread-name thread))
+ (defimplementation thread-name (thread)
+ (threads:thread-name thread))
-(defimplementation thread-status (thread)
- (format nil "Thread is ~:[dead~;alive~]" (ext:thread-alive-p thread)))
+ (defimplementation thread-status (thread)
+ (format nil "Thread is ~:[dead~;alive~]" (threads:thread-alive-p thread)))
-(defimplementation make-lock (&key name)
- (ext:make-thread-lock))
-
-(defimplementation call-with-lock-held (lock function)
- (ext:with-thread-lock (lock) (funcall function)))
-
-(defimplementation current-thread ()
- (ext:current-thread))
-
-(defimplementation all-threads ()
- (copy-list (ext:mapcar-threads #'identity)))
-
-(defimplementation interrupt-thread (thread fn)
- (ext:interrupt-thread thread fn))
-
-(defimplementation kill-thread (thread)
- (ext:destroy-thread thread))
-
-(defstruct mailbox
- (mutex (ext:make-mutex))
- (queue '()))
-
-(defun mailbox (thread)
- "Return THREAD's mailbox."
- (ext:with-thread-lock (*thread-props-lock*)
- (or (getf (gethash thread *thread-props*) 'mailbox)
- (setf (getf (gethash thread *thread-props*) 'mailbox)
- (make-mailbox)))))
-
-(defimplementation send (thread object)
- (let ((mbox (mailbox thread)))
- (ext:with-mutex ((mailbox-mutex mbox))
- (setf (mailbox-queue mbox)
- (nconc (mailbox-queue mbox) (list message))))))
-
-#+(or)
-(defimplementation receive-if (thread &optional timeout)
- (let* ((mbox (mailbox (current-thread))))
- (assert (or (not timeout) (eq timeout t)))
- (loop
- (check-slime-interrupts)
- (ext:with-mutex ((mailbox-mutex mbox))
- (let* ((q (mailbox-queue mbox))
- (tail (member-if test q)))
- (when tail
- (setf (mailbox-queue mbox) (nconc (ldiff q tail) (cdr tail)))
- (return (car tail))))
- (when (eq timeout t) (return (values nil t)))
- ;;(java:jcall (java:jmethod "java.lang.Object" "wait")
- ;; (mailbox-mutex mbox) 1000)
- ))))
+ ;; XXX should be a weak hash table
+ (defparameter *thread-description-map* (make-hash-table))
+
+ (defimplementation thread-description (thread)
+ (synchronized-on *thread-description-map*
+ (or (gethash thread *thread-description-map*)
+ "No description available.")))
+
+ (defimplementation set-thread-description (thread description)
+ (synchronized-on *thread-description-map*
+ (setf (gethash thread *thread-description-map*) description)))
+
+ (defimplementation make-lock (&key name)
+ (declare (ignore name))
+ (threads:make-thread-lock))
+
+ (defimplementation call-with-lock-held (lock function)
+ (threads:with-thread-lock (lock) (funcall function)))
+
+ (defimplementation current-thread ()
+ (threads:current-thread))
+
+ (defimplementation all-threads ()
+ (copy-list (threads:mapcar-threads #'identity)))
+
+ (defimplementation thread-alive-p (thread)
+ (member thread (all-threads)))
+
+ (defimplementation interrupt-thread (thread fn)
+ (threads:interrupt-thread thread fn))
+
+ (defimplementation kill-thread (thread)
+ (threads:destroy-thread thread))
+
+ (defstruct mailbox
+ (queue '()))
+
+ (defun mailbox (thread)
+ "Return THREAD's mailbox."
+ (threads:synchronized-on *thread-plists*
+ (or (getf (gethash thread *thread-plists*) 'mailbox)
+ (setf (getf (gethash thread *thread-plists*) 'mailbox)
+ (make-mailbox)))))
+
+ (defimplementation send (thread message)
+ (let ((mbox (mailbox thread)))
+ (threads:synchronized-on mbox
+ (setf (mailbox-queue mbox)
+ (nconc (mailbox-queue mbox) (list message)))
+ (threads:object-notify-all mbox))))
+
+ (defimplementation receive-if (test &optional timeout)
+ (let* ((mbox (mailbox (current-thread))))
+ (assert (or (not timeout) (eq timeout t)))
+ (loop
+ (check-slime-interrupts)
+ (threads:synchronized-on mbox
+ (let* ((q (mailbox-queue mbox))
+ (tail (member-if test q)))
+ (when tail
+ (setf (mailbox-queue mbox) (nconc (ldiff q tail) (cdr tail)))
+ (return (car tail)))
+ (when (eq timeout t) (return (values nil t)))
+ (threads:object-wait mbox 0.3)))))))
(defimplementation quit-lisp ()
(ext:exit))
More information about the slime-cvs
mailing list