move checking for constant ALIEN-INFO into a separate function
[sbcl.git] / src / code / target-thread.lisp
index 4b89ca8..18bec35 100644 (file)
@@ -299,13 +299,16 @@ created and old ones may exit at any time."
 
 ;;;; Spinlocks
 
-(defmacro with-deadlocks ((thread lock timeout) &body forms)
+(defmacro with-deadlocks ((thread lock &optional timeout) &body forms)
+  (declare (ignorable timeout))
   (with-unique-names (prev n-thread n-lock n-timeout new)
     `(let* ((,n-thread ,thread)
             (,n-lock ,lock)
-            (,n-timeout (or ,timeout
-                            (when sb!impl::*deadline*
-                              sb!impl::*deadline-seconds*)))
+            (,n-timeout #!-sb-lutex
+                        ,(when timeout
+                           `(or ,timeout
+                                (when sb!impl::*deadline*
+                                  sb!impl::*deadline-seconds*))))
             ;; If we get interrupted while waiting for a lock, etc.
             (,prev (thread-waiting-for ,n-thread))
             (,new (if ,n-timeout
@@ -331,7 +334,7 @@ created and old ones may exit at any time."
       (when (eq old new)
         (error "Recursive lock attempt on ~S." spinlock))
       #!+sb-thread
-      (with-deadlocks (new spinlock nil)
+      (with-deadlocks (new spinlock)
         (flet ((cas ()
                  (if (sb!ext:compare-and-swap (spinlock-value spinlock) nil new)
                      (thread-yield)
@@ -440,9 +443,11 @@ HOLDING-MUTEX-P."
                             (detect-deadlock other-lock)))))))
              (deadlock-chain (thread lock)
                (let* ((other-thread (lock-owner lock))
-                      (other-lock (thread-waiting-for other-thread)))
+                      (other-lock (when other-thread
+                                    (thread-waiting-for other-thread))))
                  (cond ((not other-thread)
-                        ;; The deadlock is gone -- maybe someone timed out?
+                        ;; The deadlock is gone -- maybe someone unwound
+                        ;; from the same deadlock already?
                         (return-from check-deadlock nil))
                        ((consp other-lock)
                         ;; There's a timeout -- no deadlock.
@@ -1068,17 +1073,26 @@ have the foreground next."
 
 ;;;; The beef
 
-(defun make-thread (function &key name)
+(defun make-thread (function &key name arguments)
   #!+sb-doc
-  "Create a new thread of NAME that runs FUNCTION. When the function
+  "Create a new thread of NAME that runs FUNCTION with the argument
+list designator provided (defaults to no argument). When the function
 returns the thread exits. The return values of FUNCTION are kept
 around and can be retrieved by JOIN-THREAD."
-  #!-sb-thread (declare (ignore function name))
+  #!-sb-thread (declare (ignore function name arguments))
   #!-sb-thread (error "Not supported in unithread builds.")
+  #!+sb-thread (assert (or (atom arguments)
+                           (null (cdr (last arguments))))
+                       (arguments)
+                       "Argument passed to ~S, ~S, is an improper list."
+                       'make-thread arguments)
   #!+sb-thread
   (let* ((thread (%make-thread :name name))
          (setup-sem (make-semaphore :name "Thread setup semaphore"))
          (real-function (coerce function 'function))
+         (arguments     (if (listp arguments)
+                            arguments
+                            (list arguments)))
          (initial-function
           (named-lambda initial-thread-function ()
             ;; In time we'll move some of the binding presently done in C
@@ -1139,7 +1153,7 @@ around and can be retrieved by JOIN-THREAD."
                                (setf (thread-result thread)
                                      (cons t
                                            (multiple-value-list
-                                            (funcall real-function))))
+                                            (apply real-function arguments))))
                                ;; Try to block deferrables. An
                                ;; interrupt may unwind it, but for a
                                ;; normal exit it prevents interrupt