#| -*-Scheme-*-
-$Id: boot.scm,v 14.5 1992/12/07 19:06:39 cph Exp $
+$Id: boot.scm,v 14.6 1993/06/29 22:58:14 cph Exp $
-Copyright (c) 1988-92 Massachusetts Institute of Technology
+Copyright (c) 1988-93 Massachusetts Institute of Technology
This material was developed by the Scheme project at the Massachusetts
Institute of Technology, Department of Electrical Engineering and
(define-integrable interrupt-bit/gc #x0004)
(define-integrable interrupt-bit/global-1 #x0008)
(define-integrable interrupt-bit/kbd #x0010)
-(define-integrable interrupt-bit/global-2 #x0020)
+(define-integrable interrupt-bit/after-gc #x0020)
(define-integrable interrupt-bit/timer #x0040)
(define-integrable interrupt-bit/global-3 #x0080)
(define-integrable interrupt-bit/suspend #x0100)
;; GC & stack overflow only
(define-integrable interrupt-mask/gc-ok #x0007)
+;; GC, stack overflow, and timer only
+(define-integrable interrupt-mask/timer-ok #x0047)
+
;; Absolutely everything off
(define-integrable interrupt-mask/none #x0000)
#| -*-Scheme-*-
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/runtime/gc.scm,v 14.8 1992/02/07 19:47:24 jinx Exp $
+$Id: gc.scm,v 14.9 1993/06/29 22:58:15 cph Exp $
-Copyright (c) 1988-1992 Massachusetts Institute of Technology
+Copyright (c) 1988-93 Massachusetts Institute of Technology
This material was developed by the Scheme project at the Massachusetts
Institute of Technology, Department of Electrical Engineering and
(define (gc-flip-internal safety-margin)
(let ((start-value (hook/gc-start)))
(let ((space-remaining ((ucode-primitive garbage-collect) safety-margin)))
- (gc-abort-test space-remaining)
- (hook/gc-finish start-value space-remaining)
+ (gc-finish start-value space-remaining)
space-remaining)))
(define (purify-internal item pure-space? safety-margin)
((ucode-primitive primitive-purify) item
pure-space?
safety-margin)))
- (gc-abort-test (cdr result))
- (hook/gc-finish start-value (cdr result))
+ (gc-finish start-value (cdr result))
result)))
(define (default/gc-start)
start-value space-remaining
false)
-(define gc-boot-loading?)
-
-(define gc-boot-death-message
- "\n;; Aborting boot-load: Not enough memory to load -- Use -large option.\n")
-
-(define (gc-abort-test space-remaining)
+(define (gc-finish start-value space-remaining)
(if (< space-remaining 4096)
(if gc-boot-loading?
(let ((console ((ucode-primitive tty-output-channel 0))))
(cmdl-message/active
(lambda (port)
port
- (with-gc-notification! true gc-clean))))))))
+ (with-gc-notification! true gc-clean)))))))
+ ((ucode-primitive request-interrupts! 1) interrupt-bit/after-gc)
+ (hook/gc-finish start-value space-remaining))
+
+(define gc-boot-loading?)
+
+(define gc-boot-death-message
+ "\n;; Aborting boot-load: Not enough memory to load -- Use -large option.\n")
\f
;;;; User Primitives
#| -*-Scheme-*-
-$Id: gcdemn.scm,v 14.5 1993/06/25 21:09:08 gjr Exp $
+$Id: gcdemn.scm,v 14.6 1993/06/29 22:58:16 cph Exp $
Copyright (c) 1988-1993 Massachusetts Institute of Technology
(declare (usual-integrations))
\f
(define (initialize-package!)
+ (set! primitive-gc-daemons (make-queue))
+ (set! trigger-primitive-gc-daemons! (make-trigger primitive-gc-daemons))
+ (set! add-primitive-gc-daemon! (make-adder primitive-gc-daemons))
(set! gc-daemons (make-queue))
+ (set! trigger-gc-daemons! (make-trigger gc-daemons))
+ (set! add-gc-daemon! (make-adder gc-daemons))
(set! secondary-gc-daemons (make-queue))
+ (set! trigger-secondary-gc-daemons! (make-trigger secondary-gc-daemons))
+ (set! add-secondary-gc-daemon! (make-adder secondary-gc-daemons))
(let ((fixed-objects (get-fixed-objects-vector)))
- (vector-set! fixed-objects #x0B trigger-gc-daemons)
+ (vector-set! fixed-objects #x0B trigger-primitive-gc-daemons!)
((ucode-primitive set-fixed-objects-vector!) fixed-objects)))
+;;; PRIMITIVE-GC-DAEMONS are executed during the GC. They must not
+;;; allocate any storage and they must be prepared to run at times
+;;; when many data structures are not consistent.
+(define primitive-gc-daemons)
+(define trigger-primitive-gc-daemons!)
+(define add-primitive-gc-daemon!)
+
+;;; GC-DAEMONS are executed after each GC from an interrupt handler.
+;;; This interrupt handler has lower priority than the GC interrupt,
+;;; which guarantees that these daemons will not be run inside of
+;;; critical sections. As a result, the daemons may allocate storage
+;;; and use most of the runtime facilities.
(define gc-daemons)
-(define secondary-gc-daemons)
-
-(define (invoke-thunk thunk)
- (thunk))
+(define trigger-gc-daemons!)
+(define add-gc-daemon!)
-(define (trigger-gc-daemons)
- (for-each invoke-thunk
- (queue->list/unsafe gc-daemons)))
-
-(define (trigger-secondary-gc-daemons!)
- (for-each invoke-thunk
- (queue->list/unsafe secondary-gc-daemons)))
+;;; SECONDARY-GC-DAEMONS are executed rarely. Their purpose is to
+;;; reclaim storage that is either unlikely to be reclaimed or
+;;; expensive to reclaim.
+(define secondary-gc-daemons)
+(define trigger-secondary-gc-daemons!)
+(define add-secondary-gc-daemon!)
-(define (add-gc-daemon! daemon)
- (enqueue! gc-daemons daemon))
+(define (make-trigger daemons)
+ (lambda ()
+ (for-each (lambda (thunk) (thunk))
+ (queue->list/unsafe daemons))))
-(define (add-secondary-gc-daemon! daemon)
- (enqueue! secondary-gc-daemons daemon))
+(define (make-adder daemons)
+ (lambda (daemon)
+ (enqueue! daemons daemon)))
(define (gc-clean #!optional threshold)
(let ((threshold
#| -*-Scheme-*-
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/runtime/hash.scm,v 14.4 1991/08/18 23:33:20 cph Exp $
+$Id: hash.scm,v 14.5 1993/06/29 22:58:17 cph Exp $
-Copyright (c) 1988-91 Massachusetts Institute of Technology
+Copyright (c) 1988-93 Massachusetts Institute of Technology
This material was developed by the Scheme project at the Massachusetts
Institute of Technology, Department of Electrical Engineering and
(set! all-hash-tables (weak-cons 0 '()))
(set! default-hash-table (hash-table/make))
(add-event-receiver! event:after-restore (lambda () (gc-flip)))
- (add-gc-daemon! rehash-all-gc-daemon))
+ (add-primitive-gc-daemon! rehash-all-gc-daemon))
(define-structure (hash-table
(conc-name hash-table/)
#| -*-Scheme-*-
-$Id: intrpt.scm,v 14.13 1993/04/29 05:24:34 cph Exp $
+$Id: intrpt.scm,v 14.14 1993/06/29 22:58:18 cph Exp $
Copyright (c) 1988-93 Massachusetts Institute of Technology
;;;; Interrupt System
;;; package: (runtime interrupt-handler)
-(declare (usual-integrations))
+(declare (usual-integrations)
+ (integrate-external "boot"))
\f
(define (initialize-package!)
(set! index:interrupt-vector
(fixed-objects-vector-slot 'SYSTEM-INTERRUPT-VECTOR))
+ (set! index:interrupt-mask-vector
+ (fixed-objects-vector-slot 'INTERRUPT-MASK-VECTOR))
(set! index:termination-vector
(fixed-objects-vector-slot 'MICROCODE-TERMINATIONS-PROCEDURES))
(set! hook/clean-input/flush-typeahead false)
(real-timer-clear 0))
(define-integrable stack-overflow-slot 0)
-(define-integrable global-gc-slot 1)
(define-integrable gc-slot 2)
(define-integrable character-slot 4)
+(define-integrable after-gc-slot 5)
(define-integrable timer-slot 6)
(define-integrable suspend-slot 8)
(define-integrable illegal-interrupt-slot 9)
(define index:interrupt-vector)
+(define index:interrupt-mask-vector)
(define index:termination-vector)
\f
;;;; Miscellaneous Interrupts
args
(abort->nearest "Aborting! Out of memory"))
+(define (after-gc-interrupt-handler interrupt-code interrupt-enables)
+ interrupt-code interrupt-enables
+ (trigger-gc-daemons!)
+ ;; By clearing the interrupt after running the daemons we ignore an
+ ;; GC that occurs while we are running the daemons. This helps
+ ;; prevent us from getting into a loop just running the daemons.
+ (clear-interrupts! interrupt-bit/after-gc))
+
(define (illegal-interrupt-handler interrupt-code interrupt-enables)
(error "Illegal interrupt" interrupt-code interrupt-enables))
(define (install)
(without-interrupts
(lambda ()
- (let ((old-system-interrupt-vector
+ (let ((system-interrupt-vector
(vector-ref (get-fixed-objects-vector) index:interrupt-vector))
+ (old-interrupt-mask-vector
+ (vector-ref (get-fixed-objects-vector)
+ index:interrupt-mask-vector))
(old-termination-vector
(vector-ref (get-fixed-objects-vector) index:termination-vector)))
- (let ((previous-gc-interrupt
- (vector-ref old-system-interrupt-vector gc-slot))
- (previous-global-gc-interrupt
- (vector-ref old-system-interrupt-vector global-gc-slot))
- (previous-stack-interrupt
- (vector-ref old-system-interrupt-vector stack-overflow-slot))
- (system-interrupt-vector
- (make-vector (vector-length old-system-interrupt-vector)
- default-interrupt-handler))
+ (let ((interrupt-mask-vector
+ (let ((length (vector-length system-interrupt-vector)))
+ (if (and (vector? old-interrupt-mask-vector)
+ (= (vector-length old-interrupt-mask-vector) length))
+ old-interrupt-mask-vector
+ (let ((masks (make-vector length)))
+ (do ((i 0 (+ i 1)))
+ ((= i length))
+ (vector-set! masks i (- (expt 2 i) 1)))
+ masks))))
(termination-vector
(let ((length (microcode-termination/code-limit)))
(if old-termination-vector
(if (> length (vector-length old-termination-vector))
(vector-grow old-termination-vector length)
old-termination-vector)
- (make-vector length false)))))
+ (make-vector length #f)))))
+
+ (vector-set! interrupt-mask-vector stack-overflow-slot
+ interrupt-mask/none)
+
+ (vector-set! interrupt-mask-vector gc-slot
+ interrupt-mask/none)
- (vector-set! system-interrupt-vector gc-slot previous-gc-interrupt)
- (vector-set! system-interrupt-vector global-gc-slot
- previous-global-gc-interrupt)
- (vector-set! system-interrupt-vector stack-overflow-slot
- previous-stack-interrupt)
- (vector-set! system-interrupt-vector character-slot
- external-interrupt-handler)
(vector-set! system-interrupt-vector timer-slot
timer-interrupt-handler)
+ (vector-set! interrupt-mask-vector timer-slot
+ interrupt-mask/gc-ok)
+
+ (vector-set! system-interrupt-vector character-slot
+ external-interrupt-handler)
+ (vector-set! interrupt-mask-vector character-slot
+ interrupt-mask/timer-ok)
+
+ (vector-set! system-interrupt-vector after-gc-slot
+ after-gc-interrupt-handler)
+ (vector-set! interrupt-mask-vector after-gc-slot
+ interrupt-mask/timer-ok)
+
(vector-set! system-interrupt-vector suspend-slot
suspend-interrupt-handler)
+ (vector-set! interrupt-mask-vector suspend-slot
+ interrupt-mask/timer-ok)
+
(vector-set! system-interrupt-vector illegal-interrupt-slot
illegal-interrupt-handler)
-
- ;; install the new vector atomically
- (vector-set! (get-fixed-objects-vector)
- index:interrupt-vector
- system-interrupt-vector)
+ (vector-set! interrupt-mask-vector illegal-interrupt-slot
+ interrupt-mask/timer-ok)
(vector-set! termination-vector
(microcode-termination 'GC-OUT-OF-SPACE)
gc-out-of-space-handler)
+ ;; Install the new tables atomically:
+
+ (vector-set! (get-fixed-objects-vector)
+ index:interrupt-mask-vector
+ interrupt-mask-vector)
+
(vector-set! (get-fixed-objects-vector)
index:termination-vector
termination-vector)
#| -*-Scheme-*-
-$Id: runtime.pkg,v 14.180 1993/06/10 06:07:45 gjr Exp $
+$Id: runtime.pkg,v 14.181 1993/06/29 22:58:20 cph Exp $
Copyright (c) 1988-1993 Massachusetts Institute of Technology
add-secondary-gc-daemon!
gc-clean
trigger-secondary-gc-daemons!)
+ (export (runtime hash)
+ add-primitive-gc-daemon!)
+ (export (runtime interrupt-handler)
+ trigger-gc-daemons!)
(initialization (initialize-package!)))
(define-package (runtime gc-notification)
#| -*-Scheme-*-
-$Id: version.scm,v 14.162 1993/06/25 21:09:55 gjr Exp $
+$Id: version.scm,v 14.163 1993/06/29 22:58:21 cph Exp $
Copyright (c) 1988-1993 Massachusetts Institute of Technology
'()))
(add-system! microcode-system)
(add-event-receiver! event:after-restore snarf-microcode-version!)
- (add-identification! "Runtime" 14 162))
+ (add-identification! "Runtime" 14 163))
(define microcode-system)
#| -*-Scheme-*-
-$Id: runtime.pkg,v 14.180 1993/06/10 06:07:45 gjr Exp $
+$Id: runtime.pkg,v 14.181 1993/06/29 22:58:20 cph Exp $
Copyright (c) 1988-1993 Massachusetts Institute of Technology
add-secondary-gc-daemon!
gc-clean
trigger-secondary-gc-daemons!)
+ (export (runtime hash)
+ add-primitive-gc-daemon!)
+ (export (runtime interrupt-handler)
+ trigger-gc-daemons!)
(initialization (initialize-package!)))
(define-package (runtime gc-notification)