(define-integrable (interrupt-mask-ok?)
(fix:= 0 (get-interrupt-enables)))
+(define-integrable (lock)
+ ;; (%assert (eq? interrupt-mask/all (get-interrupt-enables)) "lock: unexpected interrupt mask")
+ (%assert (not locked?) "lock: already locked!")
+ (set-interrupt-enables! interrupt-mask/in-threads)
+ (%lock))
+
(define (%lock)
- (%assert (interrupt-mask-ok?) "%lock: wrong interrupt mask")
- (%assert (not locked?) "%lock: already locked")
(if enable-smp?
(if (not (eq? #t ((ucode-primitive smp-lock-threads 1) #t)))
(error "Could not lock the thread system.")))
(set! locked? #t))
+(define-integrable (unlock)
+ (%assert (interrupt-mask-ok?) "unlock: wrong interrupt mask")
+ (%assert locked? "unlock: not locked")
+ (%unlock)
+ (set-interrupt-enables! interrupt-mask/all))
+
(define (%unlock)
- (%assert (interrupt-mask-ok?) "%unlock: wrong interrupt mask")
- (%assert locked? "%unlock: not locked")
(set! locked? #f)
(if enable-smp?
(if (not (eq? #t ((ucode-primitive smp-lock-threads 1) #f)))
(%outf-error "%unlock: failed"))))
-(define-integrable (without-interrupts thunk)
- (let ((interrupt-mask (set-interrupt-enables! interrupt-mask/in-threads)))
- (let ((value (thunk)))
- (set-interrupt-enables! interrupt-mask)
- value)))
-
(define-integrable (with-thread-lock thunk)
- (let ((interrupt-mask (set-interrupt-enables! interrupt-mask/in-threads)))
- (%lock)
- (let ((value (thunk)))
- (%unlock)
- (set-interrupt-enables! interrupt-mask)
- value)))
+ (lock)
+ (let ((value (thunk)))
+ (unlock)
+ value))
(define (with-obarray-lock thunk)
;; Serialize with myriad parts of the microcode that hack the
(handle-thread-events thread)
(%maybe-toggle-thread-timer)
(set-thread/block-events?! thread #f)))
- (%unlock))
+ (unlock))
(define (suspend-current-thread)
- (set-interrupt-enables! interrupt-mask/in-threads)
- (%lock)
+ (lock)
(%suspend-thread first-running-thread))
(define (%suspend-thread thread)
(if any-events?
(begin
(%maybe-toggle-thread-timer)
- (%unlock))
+ (unlock))
(call-with-current-continuation
(lambda (continuation)
(set-thread/continuation! thread continuation)
(let ((thread first-running-thread))
(set-thread/continuation! thread continuation)
(maybe-save-thread-float-environment! thread)
- (set-interrupt-enables! interrupt-mask/in-threads)
- (%lock)
+ (lock)
(thread-not-running thread 'STOPPED)))))
(define (restart-thread thread discard-events? event)
(prompt-for-confirmation
"Restarting other thread; discard events in its queue")
discard-events?)))
- (let ((mask (set-interrupt-enables! interrupt-mask/in-threads)))
- (%lock)
- (if (not (eq? 'STOPPED (thread/execution-state thread)))
- (begin
- (%unlock)
- (set-interrupt-enables! mask)
- (error:bad-range-argument thread restart-thread))
- (begin
- (if discard-events?
- (ring/discard-all (thread/pending-events thread)))
- (if event
- (%signal-thread-event thread event))
- (thread-running thread))))))
+ (lock)
+ (if (not (eq? 'STOPPED (thread/execution-state thread)))
+ (begin
+ (unlock)
+ (error:bad-range-argument thread restart-thread))
+ (begin
+ (if discard-events?
+ (ring/discard-all (thread/pending-events thread)))
+ (if event
+ (%signal-thread-event thread event))
+ (thread-running thread)))))
\f
(define (disallow-preempt-current-thread)
(set-thread/execution-state! (current-thread) 'RUNNING-WITHOUT-PREEMPTION))
(let ((thread first-running-thread))
(cond ((not thread)
(%maybe-toggle-thread-timer)
- (%unlock))
+ (unlock))
((thread/continuation thread)
(run-thread thread))
((not (eq? 'RUNNING-WITHOUT-PREEMPTION
(%resume-thread thread))))))
(define (yield-current-thread)
- (without-interrupts
- (lambda ()
- (%lock)
- (let ((thread first-running-thread))
- ;; Allow preemption now, since the current thread has
- ;; volunteered to yield control.
- (set-thread/execution-state! thread 'RUNNING)
- (yield-thread thread)))))
+ (lock)
+ (let ((thread first-running-thread))
+ ;; Allow preemption now, since the current thread has
+ ;; volunteered to yield control.
+ (set-thread/execution-state! thread 'RUNNING)
+ (yield-thread thread)))
(define (yield-thread thread #!optional fp-env)
(%assert-locked 'yield-thread)
(let ((thread (current-thread)))
(set-thread/block-events?! thread #t)
(dynamic-unwind thread (thread/root-dynamic-state thread))
- (set-interrupt-enables! interrupt-mask/in-threads)
- (%lock)
+ (lock)
(ring/discard-all (thread/pending-events thread))
(%deregister-io-thread-events thread)
(%discard-thread-timer-records thread)
(let ((self first-running-thread))
(if (eq? thread self)
(signal-thread-deadlock self "join thread" join-thread thread)
- (let ((mask (set-interrupt-enables! interrupt-mask/in-threads)))
- (%lock)
+ (begin
+ (lock)
(let ((value (thread/exit-value thread)))
(cond ((eq? value no-exit-value-marker)
(set-thread/joined-threads!
(set-thread/joined-to!
self
(cons thread (thread/joined-to self)))
- (%unlock)
- (set-interrupt-enables! mask))
+ (unlock))
((eq? value detached-thread-marker)
- (%unlock)
- (set-interrupt-enables! mask)
+ (unlock)
(signal-thread-detached thread))
(else
- (%unlock)
- (set-interrupt-enables! mask)
+ (unlock)
(signal-thread-event
self
;; Executed in the dynamic state of SELF, not THREAD(!).
(define (detach-thread thread)
(guarantee-thread thread 'DETACH-THREAD)
- (let ((mask (set-interrupt-enables! interrupt-mask/in-threads)))
- (%lock)
- (if (eq? (thread/exit-value thread) detached-thread-marker)
- (begin
- (%unlock)
- (set-interrupt-enables! mask)
- (signal-thread-detached thread))
- (begin
- (release-joined-threads thread detached-thread-marker)
- (%unlock)
- (set-interrupt-enables! mask))))
+ (lock)
+ (if (eq? (thread/exit-value thread) detached-thread-marker)
+ (begin
+ (unlock)
+ (signal-thread-detached thread))
+ (begin
+ (release-joined-threads thread detached-thread-marker)
+ (unlock)))
thread)
(define detached-thread-marker
((eq? 'PROCESS-STATUS-CHANGE result)
(%handle-subprocess-status-change))
((eq? 'INTERRUPT result)
- (%unlock)
- (set-interrupt-enables! interrupt-mask/all)
+ (unlock)
(handle-interrupts)
- (set-interrupt-enables! interrupt-mask/in-threads)
- (%lock))))
+ (lock))))
(define (handle-interrupts)
#t)
\f
(define (signal-thread-event thread event)
(guarantee-thread thread 'SIGNAL-THREAD-EVENT)
- (if (eq? thread first-running-thread)
- (let ((block-events? (block-thread-events)))
- (with-thread-lock
- (lambda ()
- (%add-pending-event thread event)))
- (if (not block-events?)
- (unblock-thread-events)))
- (let ((mask (set-interrupt-enables! interrupt-mask/in-threads)))
- (%lock)
- (if (eq? 'DEAD (thread/execution-state thread))
- (begin
- (%unlock)
- (set-interrupt-enables! mask)
- (signal-thread-dead thread "signal event to"
- signal-thread-event thread event))
- (begin
- (%signal-thread-event thread event)
- (%maybe-toggle-thread-timer)
- (%unlock)
- (set-interrupt-enables! mask))))))
+ (let ((self first-running-thread))
+ (if (eq? thread self)
+ (let ((block-events? (block-thread-events)))
+ (with-thread-lock
+ (lambda ()
+ (%add-pending-event thread event)))
+ (if (not block-events?)
+ (unblock-thread-events)))
+ (begin
+ (lock)
+ (if (eq? 'DEAD (thread/execution-state thread))
+ (begin
+ (unlock)
+ (signal-thread-dead thread "signal event to"
+ signal-thread-event thread event))
+ (begin
+ (%signal-thread-event thread event)
+ (%maybe-toggle-thread-timer)
+ (unlock)))))))
(define (%signal-thread-event thread event)
(%assert-locked '%signal-thread-event)
(if event
(let ((block? (thread/block-events? thread)))
(set-thread/block-events?! thread #t)
- (%unlock)
- (set-interrupt-enables! interrupt-mask/all)
+ (unlock)
(event)
- (set-interrupt-enables! interrupt-mask/in-threads)
- (%lock)
+ (lock)
(set-thread/block-events?! thread block?)))
(loop #t))))))
(define (lock-thread-mutex mutex)
(guarantee-thread-mutex mutex 'LOCK-THREAD-MUTEX)
- (let ((mask (set-interrupt-enables! interrupt-mask/in-threads)))
- (%lock)
- (let ((thread first-running-thread)
- (owner (thread-mutex/owner mutex)))
- (if (eq? owner thread)
- (begin
- (%unlock)
- (set-interrupt-enables! mask)
- (signal-thread-deadlock thread "lock thread mutex"
- lock-thread-mutex mutex))
- (begin
- (%lock-thread-mutex mutex thread owner)
- (%unlock)
- (set-interrupt-enables! mask))))))
+ (lock)
+ (let ((thread first-running-thread)
+ (owner (thread-mutex/owner mutex)))
+ (if (eq? owner thread)
+ (begin
+ (unlock)
+ (signal-thread-deadlock thread "lock thread mutex"
+ lock-thread-mutex mutex))
+ (begin
+ (%lock-thread-mutex mutex thread owner)
+ (unlock)))))
(define (%lock-thread-mutex mutex thread owner)
(%assert-locked '%lock-thread-mutex)
(ring/enqueue (thread-mutex/waiting-threads mutex) thread)
(do () ((eq? thread (thread-mutex/owner mutex)))
(%suspend-thread thread)
- (%lock)))
+ (lock)))
(set-thread-mutex/owner! mutex thread)))
(define (unlock-thread-mutex mutex)
(guarantee-thread-mutex mutex 'UNLOCK-THREAD-MUTEX)
- (let ((mask (set-interrupt-enables! interrupt-mask/in-threads)))
- (%lock)
- (let ((thread first-running-thread)
- (owner (thread-mutex/owner mutex)))
- (if (and owner (not (eq? owner thread)))
- (begin
- (%unlock)
- (set-interrupt-enables! mask)
- (error "Don't own mutex:" mutex))
- (begin
- (%unlock-thread-mutex mutex owner)
- (%unlock)
- (set-interrupt-enables! mask))))))
+ (lock)
+ (let ((thread first-running-thread)
+ (owner (thread-mutex/owner mutex)))
+ (if (and owner (not (eq? owner thread)))
+ (begin
+ (unlock)
+ (error "Don't own mutex:" mutex))
+ (begin
+ (%unlock-thread-mutex mutex owner)
+ (unlock)))))
(define (%unlock-thread-mutex mutex owner)
(%assert-locked '%unlock-thread-mutex)