[slime-cvs] CVS update: slime/ChangeLog slime/swank-sbcl.lisp

Christophe Rhodes crhodes at common-lisp.net
Fri Jul 1 13:52:57 UTC 2005


Update of /project/slime/cvsroot/slime
In directory common-lisp.net:/tmp/cvs-serv29206

Modified Files:
	ChangeLog swank-sbcl.lisp 
Log Message:
Patch from Gabor for new thread api support (older SBCLs may or may 
not work at all, but definitely don't work with threads)

Date: Fri Jul  1 15:52:56 2005
Author: crhodes

Index: slime/ChangeLog
diff -u slime/ChangeLog:1.717 slime/ChangeLog:1.718
--- slime/ChangeLog:1.717	Tue Jun 28 10:40:07 2005
+++ slime/ChangeLog	Fri Jul  1 15:52:55 2005
@@ -1,3 +1,8 @@
+2005-07-01  Gabor Melis  <mega at hotpop.com>
+
+	* swank-sbcl.lisp (threaded stuff): make SBCL 0.9.2.9+ work while
+	retaining support for 0.9.2
+
 2005-06-28  Gabor Melis <mega at hotpop.com>
 
 	* swank-sbcl.lisp (threaded stuff): horrible hack to make threaded


Index: slime/swank-sbcl.lisp
diff -u slime/swank-sbcl.lisp:1.135 slime/swank-sbcl.lisp:1.136
--- slime/swank-sbcl.lisp:1.135	Tue Jun 28 10:40:07 2005
+++ slime/swank-sbcl.lisp	Fri Jul  1 15:52:55 2005
@@ -504,7 +504,8 @@
 #-swank-backend::source-plist
 (defun function-source-location (function &optional name)
   "Try to find the canonical source location of FUNCTION."
-  (declare (type function function))
+  (declare (type function function)
+           (ignore name))
   (if (function-from-emacs-buffer-p function)
       (find-temp-function-source-location function)
       (find-function-source-location function)))
@@ -512,7 +513,8 @@
 #+swank-backend::source-plist
 (defun function-source-location (function &optional name)
   "Try to find the canonical source location of FUNCTION."
-  (declare (type function function))
+  (declare (type function function)
+           (ignore name))
   (find-function-source-location function))
 
 (defun safe-function-source-location (fun name)
@@ -1086,7 +1088,130 @@
 
 ;;;; Multiprocessing
 
-#+sb-thread
+#+(and sb-thread
+       #.(cl:if (cl:find-symbol "THREAD-NAME" "SB-THREAD") '(and) '(or)))
+(progn
+  (defvar *thread-id-counter* 0)
+  
+  (defvar *thread-id-counter-lock*
+    (sb-thread:make-mutex :name "thread id counter lock"))
+
+  (defun next-thread-id ()
+    (sb-thread:with-mutex (*thread-id-counter-lock*)
+      (incf *thread-id-counter*)))
+  
+  (defparameter *thread-id-map* (make-hash-table))
+
+  ;; This should be a thread -> id map but as weak keys are not
+  ;; supported it is id -> map instead.
+  (defvar *thread-id-map-lock*
+    (sb-thread:make-mutex :name "thread id map lock"))
+  
+  (defimplementation spawn (fn &key name)
+    (sb-thread:make-thread fn :name name))
+
+  (defimplementation startup-multiprocessing ())
+
+  (defimplementation thread-id (thread)
+    (sb-thread:with-mutex (*thread-id-map-lock*)
+      (loop for id being the hash-key in *thread-id-map*
+            using (hash-value thread-pointer)
+            do
+            (let ((maybe-thread (sb-ext:weak-pointer-value thread-pointer)))
+              (cond ((null maybe-thread)
+                     ;; the value is gc'd, remove it manually
+                     (remhash id *thread-id-map*))
+                    ((eq thread maybe-thread)
+                     (return-from thread-id id)))))
+      ;; lazy numbering
+      (let ((id (next-thread-id)))
+        (setf (gethash id *thread-id-map*) (sb-ext:make-weak-pointer thread))
+        id)))
+
+  (defimplementation find-thread (id)
+    (sb-thread:with-mutex (*thread-id-map-lock*)
+      (let ((thread-pointer (gethash id *thread-id-map*)))
+        (if thread-pointer
+            (let ((maybe-thread (sb-ext:weak-pointer-value thread-pointer)))
+              (if maybe-thread
+                  maybe-thread
+                  ;; the value is gc'd, remove it manually
+                  (progn
+                    (remhash id *thread-id-map*)
+                    nil)))
+            nil))))
+  
+  (defimplementation thread-name (thread)
+    ;; sometimes the name is not a string (e.g. NIL)
+    (princ-to-string (sb-thread:thread-name thread)))
+
+  (defimplementation thread-status (thread)
+    (if (sb-thread:thread-alive-p thread)
+        "RUNNING"
+        "STOPPED"))
+
+  (defimplementation make-lock (&key name)
+    (sb-thread:make-mutex :name name))
+
+  (defimplementation call-with-lock-held (lock function)
+    (declare (type function function))
+    (sb-thread:with-mutex (lock) (funcall function)))
+
+  (defimplementation current-thread ()
+    sb-thread:*current-thread*)
+
+  (defimplementation all-threads ()
+    (sb-thread:list-all-threads))
+ 
+  (defimplementation interrupt-thread (thread fn)
+    (sb-thread:interrupt-thread thread fn))
+
+  (defimplementation kill-thread (thread)
+    (sb-thread:terminate-thread thread))
+
+  (defimplementation thread-alive-p (thread)
+    (sb-thread:thread-alive-p thread))
+
+  (defvar *mailbox-lock* (sb-thread:make-mutex :name "mailbox lock"))
+  (defvar *mailboxes* (list))
+  (declaim (type list *mailboxes*))
+
+  (defstruct (mailbox (:conc-name mailbox.)) 
+    thread
+    (mutex (sb-thread:make-mutex))
+    (waitqueue  (sb-thread:make-waitqueue))
+    (queue '() :type list))
+
+  (defun mailbox (thread)
+    "Return THREAD's mailbox."
+    (sb-thread:with-mutex (*mailbox-lock*)
+      (or (find thread *mailboxes* :key #'mailbox.thread)
+          (let ((mb (make-mailbox :thread thread)))
+            (push mb *mailboxes*)
+            mb))))
+
+  (defimplementation send (thread message)
+    (let* ((mbox (mailbox thread))
+           (mutex (mailbox.mutex mbox)))
+      (sb-thread:with-mutex (mutex)
+        (setf (mailbox.queue mbox)
+              (nconc (mailbox.queue mbox) (list message)))
+        (sb-thread:condition-broadcast (mailbox.waitqueue mbox)))))
+
+  (defimplementation receive ()
+    (let* ((mbox (mailbox (current-thread)))
+           (mutex (mailbox.mutex mbox)))
+      (sb-thread:with-mutex (mutex)
+        (loop
+         (let ((q (mailbox.queue mbox)))
+           (cond (q (return (pop (mailbox.queue mbox))))
+                 (t (sb-thread:condition-wait (mailbox.waitqueue mbox)
+                                              mutex))))))))
+
+  )
+
+#+(and sb-thread
+       #.(cl:if (cl:find-symbol "THREAD-NAME" "SB-THREAD") '(or) '(and)))
 (progn
   (defimplementation spawn (fn &key name)
     (declare (ignore name))




More information about the slime-cvs mailing list