(lambda ()
(set! constant-space-queue (cons item constant-space-queue))
unspecific))
- (purify-internal item default-safety-margin))))
+ (with-absolutely-no-interrupts
+ (lambda ()
+ (purify-internal item default-safety-margin))))))
(define (default/stack-overflow)
(abort->nearest "Aborting!: maximum recursion depth exceeded"))
(define hook/gc-finish)
(define (gc-flip-internal safety-margin)
- (let ((start-value (hook/gc-start)))
- (let ((space-remaining ((ucode-primitive garbage-collect) safety-margin)))
- (gc-finish start-value space-remaining)
- space-remaining)))
+ (with-gc-lock
+ (lambda ()
+ (let ((start-value (hook/gc-start)))
+ (let ((space-remaining
+ ((ucode-primitive garbage-collect) safety-margin)))
+ (gc-finish start-value space-remaining)
+ space-remaining)))))
(define (purify-internal item safety-margin)
- (let ((start-value (hook/gc-start)))
- (let ((result
- ((ucode-primitive primitive-purify) item #f safety-margin)))
- (gc-finish start-value (cdr result))
- (cdr result))))
+ (with-gc-lock
+ (lambda ()
+ (let ((start-value (hook/gc-start)))
+ (let ((result
+ ((ucode-primitive primitive-purify) item #f safety-margin)))
+ (gc-finish start-value (cdr result))
+ (cdr result))))))
(define (default/gc-start)
#f)
(let ((do-it
(lambda ()
(let loop ()
- (if (not ((ucode-primitive primitive-fasdump)
- object filename dump-option))
+ (if (not (with-heap-lock
+ (lambda ()
+ ((ucode-primitive primitive-fasdump)
+ object filename dump-option))))
(begin
(with-simple-restart 'RETRY "Try again."
(lambda ()
args
(abort->nearest "Aborting! Out of memory"))
+(define (global-gc-interrupt-handler interrupt-code interrupt-enables)
+ interrupt-code interrupt-enables
+ ((ucode-primitive smp-gc-wait 0)))
+
(define after-gc-interrupt-handler
(let ((running? #f))
(named-lambda (after-gc-interrupt-handler interrupt-code interrupt-enables)
with-values
write-to-string)
(import (runtime thread)
+ with-heap-lock
with-obarray-lock)
(initialization (initialize-package!)))
hook/hardware-trap)
(export (runtime thread)
abort-if-heap-low)
+ (import (runtime thread)
+ with-gc-lock)
(initialization (initialize-package!)))
(define-package (runtime gc-daemons)
(set-interrupt-enables! mask)
value)))
+(define (with-gc-lock thunk)
+ ;; Serialize processors for GC and purify.
+ (%assert (interrupt-mask-ok?) "with-gc-lock: wrong interrupt mask")
+ (if enable-smp?
+ (let ((result ((ucode-primitive smp-lock-heap 1) #t)))
+ (cond ((eq? #t result)
+ (let ((value (thunk)))
+ (if (not (eq? #t ((ucode-primitive smp-lock-heap 1) #f)))
+ (%outf-error "with-gc-lock: unlock failed"))
+ value))
+ ((eq? #f result)
+ ((ucode-primitive smp-gc-wait 0))
+ (let ((space ((ucode-primitive gc-space-status))))
+ (- (vector-ref space 14) ;shared_heap_end
+ (vector-ref space 13) ;shared_heap_free
+ )))
+ (else
+ (%assert #f "with-gc-lock: lock failed; GCing anyway...")
+ (thunk))))
+ (thunk)))
+
+(define (with-heap-lock thunk)
+ ;; Serialize other access (besides purify or GC) to the heap.
+ (let* ((mask (set-interrupt-enables! interrupt-mask/none))
+ (value
+ (if (not enable-smp?)
+ (thunk)
+ (let wait ()
+ (let ((result ((ucode-primitive smp-lock-heap 1) #t)))
+ (cond
+ ((eq? #t result)
+ (let ((value (thunk)))
+ (if (not (eq? #t ((ucode-primitive smp-lock-heap 1) #f)))
+ (%assert #f "with-heap-lock: unlock failed"))
+ value))
+ ((eq? #f result)
+ (wait))
+ (else
+ (%assert #f "with-heap-lock: lock failed")
+ #f)))))))
+ (set-interrupt-enables! mask)
+ value))
+
(define (without-preemption thunk)
(let* ((thread (current-thread))
(state (thread/execution-state thread)))