1999-09-14 08:45:02 -04:00
|
|
|
; Copyright (c) 1993-1999 by Richard Kelsey and Jonathan Rees. See file COPYING.
|
|
|
|
|
|
|
|
; Sleeping for N milliseconds.
|
|
|
|
|
2001-06-07 12:14:29 -04:00
|
|
|
(define (sleep user-n)
|
|
|
|
(let ((n (coerce-to-nonnegative-integer user-n)))
|
|
|
|
(cond ((not n)
|
|
|
|
(call-error "wrong type argument" sleep user-n))
|
|
|
|
((< 0 n)
|
2002-08-16 10:11:50 -04:00
|
|
|
(let ((cell (make-cell (current-thread))))
|
2001-06-07 12:14:29 -04:00
|
|
|
(disable-interrupts!)
|
2002-08-16 10:11:50 -04:00
|
|
|
(set-thread-cell! (current-thread) cell)
|
2002-08-20 10:03:01 -04:00
|
|
|
(insert-dozer! cell n)
|
2001-06-07 12:14:29 -04:00
|
|
|
(block))))))
|
|
|
|
|
2002-08-20 10:03:01 -04:00
|
|
|
(define (register-dozer cell user-n)
|
|
|
|
(let ((n (coerce-to-nonnegative-integer user-n)))
|
|
|
|
(cond ((not n)
|
|
|
|
(call-error "wrong type argument" sleep user-n))
|
|
|
|
((< 0 n)
|
|
|
|
(insert-dozer! cell n)
|
|
|
|
#t)
|
|
|
|
(else #f))))
|
|
|
|
|
|
|
|
(define (insert-dozer! cell n)
|
|
|
|
(set! *dozers*
|
|
|
|
(insert (cons (+ (real-time) n)
|
|
|
|
cell)
|
|
|
|
*dozers*
|
|
|
|
(lambda (frob1 frob2)
|
|
|
|
(< (car frob1) (car frob2))))))
|
|
|
|
|
2001-06-07 12:14:29 -04:00
|
|
|
(define (coerce-to-nonnegative-integer n)
|
|
|
|
(if (real? n)
|
|
|
|
(let* ((n (round n))
|
|
|
|
(n (if (exact? n)
|
|
|
|
n
|
|
|
|
(inexact->exact n))))
|
|
|
|
(if (<= 0 n)
|
|
|
|
n
|
|
|
|
#f))
|
|
|
|
#f))
|
1999-09-14 08:45:02 -04:00
|
|
|
|
2002-08-16 10:11:50 -04:00
|
|
|
(define *dozers* '()) ; List of (wakeup-time . cell)
|
1999-09-14 08:45:02 -04:00
|
|
|
|
|
|
|
(define (insert x l <)
|
|
|
|
(cond ((null? l) (list x))
|
|
|
|
((< x (car l)) (cons x l))
|
|
|
|
(else (cons (car l) (insert x (cdr l) <)))))
|
|
|
|
|
|
|
|
; Called by root scheduler, so won't be interrupted.
|
|
|
|
; This returns two values, a boolean that indicates if any threads were
|
|
|
|
; woken and the time until the next sleeper wakes. We have to check for
|
|
|
|
; threads that have been started for some other reason.
|
|
|
|
|
|
|
|
(define (wake-some-threads)
|
|
|
|
(if (null? *dozers*)
|
|
|
|
(values #f #f)
|
|
|
|
(let ((time (real-time)))
|
|
|
|
(let loop ((dozers *dozers*) (woke? #f))
|
|
|
|
(if (null? dozers)
|
|
|
|
(begin
|
|
|
|
(set! *dozers* '())
|
|
|
|
(values woke? #f))
|
2002-08-16 10:11:50 -04:00
|
|
|
(let* ((next (car dozers))
|
|
|
|
(thread (cell-ref (cdr next))))
|
|
|
|
(cond ((not thread)
|
1999-09-14 08:45:02 -04:00
|
|
|
(loop (cdr dozers) woke?))
|
|
|
|
((< time (car next))
|
|
|
|
(set! *dozers* dozers)
|
|
|
|
(values woke? (- (car next) time)))
|
|
|
|
(else
|
2002-08-16 10:11:50 -04:00
|
|
|
(make-ready thread)
|
1999-09-14 08:45:02 -04:00
|
|
|
(loop (cdr dozers) #t)))))))))
|