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"
: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
(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))
(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 ()
"malloc"
"memmove"
"mkdir"
+ "nanosleep"
"nl_langinfo"
"open"
"opendir"
;;; 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"