(set! last-runnable-thread thread)
(complain-if (not (eq? #f (thread/next thread)))
"%thread-running: last-runnable-thread has a next")
+ (%maybe-wake-idle-processor id)
unspecific)
(define (thread-not-running id thread state)
(define (reset-threads-high!)
(set! io-registry (and ((ucode-primitive have-select? 0))
(make-select-registry)))
- (set! io-registrations #f))
+ (set! io-registrations #f)
+ (set! io-waiter #f))
+
+(define io-waiter)
+
+(define (%maybe-wake-idle-processor id)
+ (%%trace ";"id" %maybe-wake-idle-processor\n")
+ (assert-locked '%maybe-wake-idle-processor)
+ (complain-if (not (only-gc-ok?))
+ "%maybe-wake-idle-processor: with interrupts")
+ (let ((len (vector-length current-threads)))
+ (let loop ((id* 0))
+ (if (fix:< id* len)
+ (if (and (not (%current-thread id*))
+ (not (fix:= id* id)))
+ (begin
+ (%%trace ";"id" waking "id*"\n")
+ ((ucode-primitive smp-wake 1) id*))
+ (loop (fix:1+ id*)))))))
(define (wait-for-io id)
;; This procedure never returns.
"wait-for-io: with interrupts")
(complain-if (%current-thread id)
"wait-for-io: not idle")
+ (if io-waiter
+ (begin
+ (%%trace ";"id" wait-for-io: idling\n")
+ (%unlock)
+ ;; This primitive never returns, but it unmasks all interrupts.
+ ((ucode-primitive smp-idle 0)))
+ (begin
+ (%%trace ";"id" wait-for-io: waiting\n")
+ (set! io-waiter id)
+ (io-waiter-wait id))))
+
+(define (io-waiter-wait id)
+ ;; This procedure never returns.
+ (%%trace ";"id" io-waiter-wait\n")
+ (assert-locked 'io-waiter-wait)
(%maybe-toggle-thread-timer #f)
- (%%trace ";"id" wait-for-io: next timeout = "next-scheduled-timeout"\n")
+ (%%trace ";"id" io-waiter-wait: next timeout = "next-scheduled-timeout"\n")
(let ((result
(begin
- (%%trace ";"id" wait-for-io: blocking for i/o\n")
+ (%%trace ";"id" io-waiter-wait: blocking for i/o\n")
(%unlock)
(set-interrupt-enables! interrupt-mask/all)
(test-select-registry io-registry #t))))
(%lock)
(signal-select-result result)
(complain-if (%current-thread id)
- "wait-for-io: ALREADY running a thread")
+ "io-waiter-wait: ALREADY running a thread")
(if first-runnable-thread
(begin
(complain-if (not (thread/continuation first-runnable-thread))
- "wait-for-io: BOGUS runnable")
- (%%trace ";"id" wait-for-io:"
+ "io-waiter-wait: BOGUS runnable")
+ (%%trace ";"id" io-waiter-wait:"
" run-first-thread "first-runnable-thread"\n")
+ (set! io-waiter #f)
(run-first-thread id))
- (wait-for-io id))))
+ (io-waiter-wait id))))
\f
(define (signal-select-result result)
(%%trace ";"(%%id)" signal-select-result"
(%lock)
(%trace ";"id" signal-thread-event: %signal\n")
(%signal-thread-event thread event)
- (if (and (not self) first-runnable-thread)
- (begin
- (%trace ";"id" signal-thread-event"
- " running "first-runnable-thread"\n")
- (run-first-thread id))
- (begin
- (%maybe-toggle-thread-timer)
- (%trace ";"id" signal-thread-event: done\n")
- (%unlock)))))))))
+ (%maybe-toggle-thread-timer)
+ (%trace ";"id" signal-thread-event: done\n")
+ (%unlock)))))))
(define (%signal-thread-event thread event)
(assert-locked '%signal-thread-event)