Clean-obarray runs as a secondary-gc-deamon and thus, in SMPing
worlds, it may run in parallel with other threads on other processors.
A number of primitives and compiler utilities modify the obarray so an
SMPing microcode will use a pthread mutex to serialize access to it.
Clean-obarray now uses a new procedure, with-obarray-lock, that uses
new primitives to participate in the serialization.
(object-new-type (ucode-type constant) 1))
\f
(define (for-each-interned-symbol procedure)
- (for-each-symbol-in-obarray (fixed-objects-item 'OBARRAY) procedure))
+ (with-obarray-lock
+ (lambda ()
+ (for-each-symbol-in-obarray (fixed-objects-item 'OBARRAY) procedure))))
(define (for-each-symbol-in-obarray obarray procedure)
(let per-bucket ((index (vector-length obarray)))
list))
(define (clean-obarray)
- (without-interrupts
+ (with-obarray-lock
(lambda ()
(let ((obarray (fixed-objects-item 'OBARRAY)))
(let loop ((index (vector-length obarray)))
with-interrupt-mask
with-values
write-to-string)
+ (import (runtime thread)
+ with-obarray-lock)
(initialization (initialize-package!)))
(define-package (runtime alternative-lambda)
(set-thread/execution-state! thread state)
value)))
+(define (with-obarray-lock thunk)
+ ;; Serialize with myriad parts of the microcode that hack the
+ ;; obarray element of the fixed-objects vector.
+ (if enable-smp?
+ (without-preemption
+ (lambda ()
+ (if (not (eq? #t ((ucode-primitive smp-lock-obarray 1) #t)))
+ (outf-error "\nwith-obarray-lock: lock failed\n"))
+ (let ((value (thunk)))
+ (if (not (eq? #t ((ucode-primitive smp-lock-obarray 1) #f)))
+ (outf-error "\nwith-obarray-lock: unlock failed\n"))
+ value)))
+ (let* ((mask (set-interrupt-enables! interrupt-mask/gc-ok))
+ (value (thunk)))
+ (set-interrupt-enables! mask)
+ value)))
+
(define (threads-list)
(map-over-population thread-population (lambda (thread) thread)))