0.8.21.20
authorDaniel Barlow <dan@telent.net>
Wed, 6 Apr 2005 17:16:57 +0000 (17:16 +0000)
committerDaniel Barlow <dan@telent.net>
Wed, 6 Apr 2005 17:16:57 +0000 (17:16 +0000)
Patch SLEEP to use nanosleep() and to restart the sleep if
interrupted e.g. by a signal, instead of returning early.  Thanks
to Gabor Melis (ref sbcl-help, "Oddity with make-thread and sleep")

package-data-list.lisp-expr
src/code/toplevel.lisp
src/code/unix.lisp
tests/threads.impure.lisp
tools-for-build/ldso-stubs.lisp
version.lisp-expr

index 2f1ba5f..551f6fc 100644 (file)
@@ -1894,6 +1894,7 @@ needed by the current implementation of SBCL, and makes
 no guarantees of interface stability."
       :use ("CL" "SB!ALIEN" "SB!EXT" "SB!INT" "SB!SYS")
       :export (        ;; wrappers around Unix stuff to give just what Lisp needs
+               "NANOSLEEP"
               "UID-USERNAME"
               "UID-HOMEDIR"
 
index 2b6dcbd..43a5c0b 100644 (file)
@@ -147,13 +147,13 @@ steppers to maintain contextual information.")
            :format-arguments (list n)
            :datum n
            :expected-type '(real 0)))
-  (multiple-value-bind (sec usec)
+  (multiple-value-bind (sec nsec)
       (if (integerp n)
          (values n 0)
          (multiple-value-bind (sec frac)
              (truncate n)
-           (values sec (truncate frac 1e-6))))
-    (sb!unix:unix-select 0 0 0 0 sec usec))
+           (values sec (truncate frac 1e-9))))
+    (sb!unix:nanosleep sec nsec))
   nil)
 \f
 ;;;; SCRUB-CONTROL-STACK
index 39b23eb..59cf350 100644 (file)
   (seconds-west sb!alien:int :out)
   (daylight-savings-p sb!alien:boolean :out))
 
+(defun nanosleep (secs nsecs)
+  (with-alien ((req (struct timespec))
+               (rem (struct timespec)))
+    (setf (slot req 'tv-sec) secs)
+    (setf (slot req 'tv-nsec) nsecs)
+    (loop while (eql sb!unix:EINTR
+                     (nth-value 1
+                                (int-syscall ("nanosleep" (* (struct timespec))
+                                                          (* (struct timespec)))
+                                             (addr req) (addr rem))))
+       do (rotatef req rem))))
+
 (defun unix-get-seconds-west (secs)
   (multiple-value-bind (ignore seconds dst) (get-timezone secs)
     (declare (ignore ignore) (ignore dst))
index 1c8b291..f33577a 100644 (file)
   (assert (eql (mutex-lock l) 0)  nil "6")
   (describe l))
 
+;; test that SLEEP actually sleeps for at least the given time, even
+;; if interrupted by another thread exiting/a gc/anything
+(let ((start-time (get-universal-time)))
+  (make-thread (lambda () (sleep 1))) ; kid waits 1 then dies ->SIG_THREAD_EXIT
+  (sleep 5)
+  (assert (>= (get-universal-time) (+ 5 start-time))))
+
+
 (let ((queue (make-waitqueue :name "queue"))
       (lock (make-mutex :name "lock")))
   (labels ((in-new-thread ()
index 500336b..5b81bf5 100644 (file)
@@ -206,6 +206,7 @@ ldso_stub__ ## fct: ;                  \\
                    "malloc"
                    "memmove"
                    "mkdir"
+                  "nanosleep"
                    "nl_langinfo"
                    "open"
                    "opendir"
index 033d273..085a0ce 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"0.8.21.19"
+"0.8.21.20"