- "Zero the unused portion of the control stack so that old objects are not
- kept alive because of uninitialized stack variables."
- ;; FIXME: Why do we need to do this instead of just letting GC read
- ;; the stack pointer and avoid messing with the unused portion of
- ;; the control stack? (Is this a multithreading thing where there's
- ;; one control stack and stack pointer per thread, and it might not
- ;; be easy to tell what a thread's stack pointer value is when
- ;; looking in from another thread?)
- (declare (optimize (speed 3) (safety 0))
- (values (unsigned-byte 20))) ; FIXME: DECLARE VALUES?
-
- #!-x86 ; machines where stack grows upwards (I guess) -- WHN 19990906
- (labels
- ((scrub (ptr offset count)
- (declare (type system-area-pointer ptr)
- (type (unsigned-byte 16) offset)
- (type (unsigned-byte 20) count)
- (values (unsigned-byte 20)))
- (cond ((= offset bytes-per-scrub-unit)
- (look (sap+ ptr bytes-per-scrub-unit) 0 count))
- (t
- (setf (sap-ref-32 ptr offset) 0)
- (scrub ptr (+ offset sb!vm:word-bytes) count))))
- (look (ptr offset count)
- (declare (type system-area-pointer ptr)
- (type (unsigned-byte 16) offset)
- (type (unsigned-byte 20) count)
- (values (unsigned-byte 20)))
- (cond ((= offset bytes-per-scrub-unit)
- count)
- ((zerop (sap-ref-32 ptr offset))
- (look ptr (+ offset sb!vm:word-bytes) count))
- (t
- (scrub ptr offset (+ count sb!vm:word-bytes))))))
- (let* ((csp (sap-int (sb!c::control-stack-pointer-sap)))
- (initial-offset (logand csp (1- bytes-per-scrub-unit))))
- (declare (type (unsigned-byte 32) csp))
- (scrub (int-sap (- csp initial-offset))
- (* (floor initial-offset sb!vm:word-bytes) sb!vm:word-bytes)
- 0)))
-
- #!+x86 ;; (Stack grows downwards.)
- (labels
- ((scrub (ptr offset count)
- (declare (type system-area-pointer ptr)
- (type (unsigned-byte 16) offset)
- (type (unsigned-byte 20) count)
- (values (unsigned-byte 20)))
- (let ((loc (int-sap (- (sap-int ptr) (+ offset sb!vm:word-bytes)))))
- (cond ((= offset bytes-per-scrub-unit)
- (look (int-sap (- (sap-int ptr) bytes-per-scrub-unit))
- 0 count))
- (t ;; need to fix bug in %SET-STACK-REF
- (setf (sap-ref-32 loc 0) 0)
- (scrub ptr (+ offset sb!vm:word-bytes) count)))))
- (look (ptr offset count)
- (declare (type system-area-pointer ptr)
- (type (unsigned-byte 16) offset)
- (type (unsigned-byte 20) count)
- (values (unsigned-byte 20)))
- (let ((loc (int-sap (- (sap-int ptr) offset))))
- (cond ((= offset bytes-per-scrub-unit)
- count)
- ((zerop (sb!kernel::get-lisp-obj-address (stack-ref loc 0)))
- (look ptr (+ offset sb!vm:word-bytes) count))
- (t
- (scrub ptr offset (+ count sb!vm:word-bytes)))))))
- (let* ((csp (sap-int (sb!c::control-stack-pointer-sap)))
- (initial-offset (logand csp (1- bytes-per-scrub-unit))))
- (declare (type (unsigned-byte 32) csp))
- (scrub (int-sap (+ csp initial-offset))
- (* (floor initial-offset sb!vm:word-bytes) sb!vm:word-bytes)
- 0))))
+ "This function causes execution to be suspended for SECONDS. SECONDS may be
+any non-negative real number."
+ (when (or (not (realp seconds))
+ (minusp seconds))
+ (error 'simple-type-error
+ :format-control "Invalid argument to SLEEP: ~S, ~
+ should be a non-negative real."
+ :format-arguments (list seconds)
+ :datum seconds
+ :expected-type '(real 0)))
+ #!-(and win32 (not sb-thread))
+ (multiple-value-bind (sec nsec)
+ (if (integerp seconds)
+ (values seconds 0)
+ (split-seconds-for-sleep seconds))
+ ;; nanosleep() accepts time_t as the first argument, but on some platforms
+ ;; it is restricted to 100 million seconds. Maybe someone can actually
+ ;; have a reason to sleep for over 3 years?
+ (loop while (> sec (expt 10 8))
+ do (decf sec (expt 10 8))
+ (sb!unix:nanosleep (expt 10 8) 0))
+ (sb!unix:nanosleep sec nsec))
+ #!+(and win32 (not sb-thread))
+ (sb!win32:millisleep (truncate (* seconds 1000)))
+ nil)