|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T i
Length: 8812 (0x226c)
Types: TextFile
Names: »io.scm.30«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/gnu-31mar87/scheme/scm/io.scm.30«
;;; -*-Scheme-*-
;;;
;;; Copyright (c) 1984 Massachusetts Institute of Technology
;;;
;;; This material was developed by the Scheme project at the
;;; Massachusetts Institute of Technology, Department of
;;; Electrical Engineering and Computer Science. Permission to
;;; copy this software, to redistribute it, and to use it for any
;;; purpose is granted, subject to the following restrictions and
;;; understandings.
;;;
;;; 1. Any copy made of this software must include this copyright
;;; notice in full.
;;;
;;; 2. Users of this software agree to make their best efforts (a)
;;; to return to the MIT Scheme project any improvements or
;;; extensions that they make, so that these may be included in
;;; future releases; and (b) to inform MIT of noteworthy uses of
;;; this software.
;;;
;;; 3. All materials developed as a consequence of the use of
;;; this software shall duly acknowledge such use, in accordance
;;; with the usual standards of acknowledging credit in academic
;;; research.
;;;
;;; 4. MIT has made no warrantee or representation that the
;;; operation of this software will be error-free, and MIT is
;;; under no obligation to provide any services, by way of
;;; maintenance, update, or otherwise.
;;;
;;; 5. In conjunction with products arising from the use of this
;;; material, there shall be no use of the name of the
;;; Massachusetts Institute of Technology nor of any adaptation
;;; thereof in any advertising, promotional, or sales literature
;;; without prior written consent from MIT in each case.
;;;
;;;; Input/output utilities
(declare (usual-integrations))
\f
(define close-all-open-files)
(define primitive-io
(make-package primitive-io
((open-files-slot (fixed-objects-vector-slot 'OPEN-FILES))
(header-size 2)
(counter-slot 0)
(file-vector-slot 1)
(default-size 10)
(buffer-size 10)
(closed-direction 0)
(make-physical-channel (make-primitive-procedure 'HUNK3-CONS))
(channel-number system-hunk3-cxr0)
(set-channel-direction! system-hunk3-set-cxr2!)
(non-marked-vector-cons
(make-primitive-procedure 'NON-MARKED-VECTOR-CONS))
(insert-non-marked-vector!
(make-primitive-procedure 'INSERT-NON-MARKED-VECTOR!))
(put-character-to-output-channel
(make-primitive-procedure 'PUT-CHARACTER-TO-OUTPUT-CHANNEL))
(print-string (make-primitive-procedure 'PRINT-STRING))
(get-character-from-input-channel
(make-primitive-procedure 'GET-CHARACTER-FROM-INPUT-CHANNEL))
(get-character-from-input-channel-immediate
(make-primitive-procedure
'GET-CHARACTER-FROM-INPUT-CHANNEL-IMMEDIATE))
)
(define channel-name
system-hunk3-cxr1)
(declare (compilable-primitive-functions
(make-physical-channel hunk3-cons)
(channel-number system-hunk3-cxr0)
(channel-name system-hunk3-cxr1)
(set-channel-direction! system-hunk3-set-cxr2!)
non-marked-vector-cons
insert-non-marked-vector!))
\f
;;;; Open/Close Files
;;; Direction is one of the following:
;;; - true: output channel
;;; - false: input channel
;;; - 0: closed channel
(define open-channel-wrapper
(let ((open-channel (make-primitive-procedure 'OPEN-CHANNEL)))
(named-lambda ((open-channel-wrapper direction) filename)
(let ((open-files-vector
(vector-ref (get-fixed-objects-vector) open-files-slot))
(file-info
(make-physical-channel
(open-channel (canonicalize-filename filename) direction)
filename
direction)))
(add-file! file-info
(if (= (vector-ref open-files-vector counter-slot)
(- (vector-size open-files-vector) header-size))
(grow-files-vector! open-files-vector)
open-files-vector))
file-info))))
(define open-input-channel (open-channel-wrapper #!FALSE))
(define open-output-channel (open-channel-wrapper #!TRUE))
(define close-physical-channel
(let ((primitive (make-primitive-procedure 'CLOSE-PHYSICAL-CHANNEL)))
(named-lambda (close-physical-channel channel)
(if (eq? closed-direction
(set-channel-direction! channel closed-direction))
#!TRUE ;Already closed!
(sequence
(primitive (channel-number channel))
(remove-from-files-vector! channel)
(channel-name channel))))))
(set! close-all-open-files
(named-lambda (close-all-open-files)
(without-interrupts
(lambda ()
(mapc close-physical-channel (all-open-channels))))))
;;; This is a crock -- it will have to be redesigned if we ever have
;;; more than one terminal connected to this system. Right now if one
;;; just opens these channels (using "CONSOLE:" and "KEYBOARD:" on the
;;; 9836), a regular file channel is opened which is both slower and
;;; will not work when restoring the band.
(define console-output-channel (make-physical-channel 0 "CONSOLE:" #!TRUE))
(define console-input-channel (make-physical-channel 0 "KEYBOARD:" #!FALSE))
(define (get-console-output-channel) console-output-channel)
(define (get-console-input-channel) console-input-channel)
(define (console-channel? channel)
(zero? (channel-number channel)))
\f
;;;; Files Vector Operations
(define (grow-files-vector! old)
(without-interrupts
(lambda ()
(let ((new (vector-cons (+ buffer-size (vector-size old)) '()))
(nm (non-marked-vector-cons
(+ buffer-size (- (vector-size old) header-size)))))
(lock-vector! old)
(let ((num (+ header-size (vector-ref old counter-slot))))
(vector-set! new counter-slot (vector-ref old counter-slot))
(insert-non-marked-vector! new file-vector-slot nm)
(lock-vector! new) ;If GC occurs it will be alright
(let loop ((current header-size))
(if (= current num)
(sequence
(clear-vector! new current
(+ buffer-size (vector-size old)))
(vector-set! (get-fixed-objects-vector) open-files-slot new)
(unlock-vector! old)
(unlock-vector! new) ;Must be done when installed!
(sequence
(vector-set! new current (vector-ref old current))
(loop (1+ current))))))
new)))))
(define (add-file! file open-files)
(without-interrupts
(lambda ()
(lock-vector! open-files)
(vector-set! open-files
(+ header-size
(vector-set! open-files
counter-slot
(1+ (vector-ref open-files counter-slot))))
file)
(unlock-vector! open-files))))
(define (remove-from-files-vector! file)
(without-interrupts
(lambda ()
(let ((open-files (vector-ref (get-fixed-objects-vector)
open-files-slot)))
(lock-vector! open-files)
(let ((max (+ header-size (vector-ref open-files counter-slot))))
(let loop ((count header-size))
(cond ((= count max)
(unlock-vector! open-files)
(error "Not an i/o channel" 'CLOSE-CHANNEL file))
((eq? file (vector-ref open-files count))
(let inner ((count (1+ count)))
(if (= count max)
(sequence
(vector-set! open-files
counter-slot
(-1+
(vector-ref open-files
counter-slot)))
(vector-set! open-files (-1+ count) '()))
(sequence
(vector-set! open-files
(-1+ count)
(vector-ref open-files count))
(inner (1+ count))))))
(else (loop (1+ count)))))
(unlock-vector! open-files))))))
\f
(define (clear-vector! v start end)
(without-interrupts
(lambda ()
(let loop ((n start))
(if (= n end)
'DONE
(sequence
(vector-set! v n '())
(loop (1+ n))))))))
(define (all-open-channels)
(let ((files-vector (vector-ref (get-fixed-objects-vector) open-files-slot)))
(without-interrupts
(lambda ()
(lock-vector! files-vector)
(let ((result
(subvector->list
files-vector
header-size
(+ header-size (vector-ref files-vector counter-slot)))))
(unlock-vector! files-vector)
result)))))
(define ((locker flag) v)
(with-interrupt-mask INTERRUPT-MASK-NONE
(lambda (old-mask)
(vector-set! v
file-vector-slot
(primitive-set-type flag
(vector-ref v file-vector-slot)))
#!true))) ; Gurantee a good value returned
(define lock-vector!
(locker (microcode-type 'NULL)))
(define unlock-vector!
(locker (microcode-type 'MANIFEST-SPECIAL-NM-VECTOR)))
(define (setup-files-vector)
(let ((base-vector (vector-cons (+ default-size header-size) '())))
(vector-set! base-vector counter-slot 0)
(insert-non-marked-vector! base-vector file-vector-slot
(non-marked-vector-cons default-size))
; (lock-vector! base-vector)
(clear-vector! base-vector header-size (+ default-size header-size))
(vector-set! (get-fixed-objects-vector) open-files-slot base-vector)
(unlock-vector! base-vector)))
\f
;;; end PRIMITIVE-IO package.
))
((access setup-files-vector primitive-io))
(add-gc-daemon! (make-primitive-procedure 'close-lost-open-files))