smp: without-interrupts: infutl.scm
authorMatt Birkholz <puck@birchwood-abbey.net>
Wed, 25 Feb 2015 15:38:41 +0000 (08:38 -0700)
committerMatt Birkholz <puck@birchwood-abbey.net>
Wed, 25 Feb 2015 15:38:41 +0000 (08:38 -0700)
README.txt
doc/user-manual/user.texinfo
src/runtime/infutl.scm
src/runtime/runtime.pkg

index 3ea1173833d887a49390a044aede62b944227577..8564a84e0344ee4a75256b8c9688fae71851e699 100644 (file)
@@ -1201,8 +1201,27 @@ The hits with accompanying analysis:
        wrappers are now all about staving off inopportune aborts.
 
   infutl.scm:90:  (without-interrupts
+       Caller: memoize-debugging-info!
+                 read-debugging-info
+                   compiled-code-block/dbg-info
+                     compiled-entry/dbg-object is exported to ()
   infutl.scm:98:  (without-interrupts
+       Caller: discard-debugging-info! is exported to ()
   infutl.scm:782:         (without-interrupts
+       Caller: call-with-uncompressed-file-pathname
+                 the if-not-found argument to lookup-uncompressed-file
+                   value of compressed-loader
+                     read-binf-file
+                       read-debugging-info (above)
+                     read-bsm-file
+                       read-labels
+                         dbg-info/labels is neither exported nor used!?
+
+       OK.  Without-interrupts was used to make atomic accesses to
+       the uncompressed-files cache and the wrappers-with-memoized-
+       debugging-info population.  To replace it, a "serial"
+       population is used and the uncompressed-files cache is punted.
+       The latter is hopefully unnecessary on modern machinery.
 
   intrpt.scm:60:  (clear-interrupts! 1)
   intrpt.scm:88:  (clear-interrupts! interrupt-bit/timer)
index b9a590327d8aab57956ab43311c8a2bc2abee9d4..288e2c375b0ce7a1a117e29c6ecf8b703984fb0d 100644 (file)
@@ -1794,60 +1794,6 @@ compiled code from that file, it attempts to find the @file{.bci} file
 in the same directory from which the @file{.com} file was loaded.  Thus
 it is a good idea to leave these files together.
 
-@file{.bci} files are stored in a compressed format.  The debugger has
-to uncompress the files when it looks at them, and on a slow machine
-this can take a noticeable time.  The system takes steps to reduce the
-impact of this behavior: debugging information is cached in memory, and
-uncompressed versions of @file{.bci} files are kept around.  The default
-behavior is that a temporary file is created and the @file{.bci} file is
-uncompressed into it.  The temporary file is kept around for a while
-afterwards, and during that time if the uncompressed @file{.bci} file is
-needed the temporary file is used.  Each such reference updates an
-`access time' that is associated with the temporary file.  The garbage
-collector checks the access times of all such temporary files, and
-deletes any that have not been accessed in five minutes or more.  All of
-the temporaries are deleted automatically when the Scheme process is
-killed.
-
-Two other behaviors are available.  One of them uncompresses the
-@file{.bci} file each time it is referenced, and the other uncompresses
-the @file{.bci} file and writes it back out as a @file{.bif} file.  The
-@file{.bif} file remains after Scheme exits.  The time interval and the
-behavior are controlled by the following variables.
-
-@defvr variable *save-uncompressed-files?*
-This variable affects what happens when @file{.bci} files are
-uncompressed.  It allows a trade-off between performance and disk space.
-There are three possible values:
-
-@table @code
-@item #f
-The uncompressed versions of @file{.bci} files are never saved.  Each
-time the information is needed the @file{.bci} file is uncompressed.
-This option requires the minimum amount of disk space and is the
-slowest.
-
-@item automatic
-Uncompressed versions of @file{.bci} files are kept as temporary files.
-The temporary files are deleted when Scheme exits, or if they have not
-been used for a while.  This is the default.
-
-@item #t
-The @file{.bci} files are uncompressed to permanent @file{.bif} files.
-These files remain on disk after Scheme exits, and are rather
-large---about twice the size of the corresponding @file{.bci} files.  If
-you choose this option and you are running out of disk space you may
-delete the @file{.bif} files.  They will be regenerated as needed.
-@end table
-@end defvr
-
-@defvr variable *uncompressed-file-lifetime*
-The minimum length of time that a temporary uncompressed version of
-a @file{.bci} file will stay on disk after it is last used.
-The time is in milliseconds; the default is @samp{300000} (five
-minutes).
-@end defvr
-
 @defvr variable load-debugging-info-on-demand?
 If this variable is @code{#f}, then printing a compiled procedure
 will print the procedure's name only if the debugging information for
index 75b387900db1747905671092541e0ad542044766..0fec72a14c5c39026ace0d0d775783994a99f76d 100644 (file)
@@ -38,11 +38,9 @@ USA.
          (,lambda-tag:let . LET)
          (,lambda-tag:fluid-let . FLUID-LET)))
   (set! directory-rewriting-rules (make-fluid '()))
-  (add-secondary-gc-daemon! discard-debugging-info!)
-  (initialize-uncompressed-files!)
-  (add-event-receiver! event:after-restore initialize-uncompressed-files!)
-  (add-event-receiver! event:before-exit delete-uncompressed-files!)
-  (add-gc-daemon! clean-uncompressed-files!))
+  (set! wrappers-with-memoized-debugging-info (make-population))
+  (set! wrappers-with-memoized-debugging-info-mutex (make-thread-mutex))
+  (add-secondary-gc-daemon! discard-debugging-info!))
 
 (define (compiled-code-block/dbg-info block demand-load?)
   (let ((wrapper (compiled-code-block/debugging-wrapper block)))
@@ -87,25 +85,23 @@ USA.
                    (loop (cdr left) time file receiver))))))))
 
 (define (memoize-debugging-info! wrapper info)
-  (without-interrupts
-   (lambda ()
-     (set-debugging-wrapper/info! wrapper info)
-     (if (not wrappers-with-memoized-debugging-info)
-        (set! wrappers-with-memoized-debugging-info (make-population)))
-     (add-to-population! wrappers-with-memoized-debugging-info wrapper))))
+  (with-thread-mutex-locked wrappers-with-memoized-debugging-info-mutex
+    (lambda ()
+      (without-interruption
+       (lambda ()
+        (set-debugging-wrapper/info! wrapper info)
+        (add-to-population! wrappers-with-memoized-debugging-info wrapper))))))
 
 (define (discard-debugging-info!)
-  (without-interrupts
-   (lambda ()
-     (if wrappers-with-memoized-debugging-info
-        (begin
-          (map-over-population! wrappers-with-memoized-debugging-info
-            (lambda (wrapper)
-              (set-debugging-wrapper/info! wrapper #f)))
-          (set! wrappers-with-memoized-debugging-info #f)))
-     unspecific)))
-
-(define wrappers-with-memoized-debugging-info #f)
+  (with-thread-mutex-locked wrappers-with-memoized-debugging-info-mutex
+    (lambda ()
+      (for-each-inhabitant wrappers-with-memoized-debugging-info
+                          (lambda (wrapper)
+                            (set-debugging-wrapper/info! wrapper #f)))
+      (empty-population! wrappers-with-memoized-debugging-info))))
+
+(define wrappers-with-memoized-debugging-info)
+(define wrappers-with-memoized-debugging-info-mutex)
 \f
 (define (compiled-entry/dbg-object entry #!optional demand-load?)
   (let ((block (compiled-entry/block entry))
@@ -463,84 +459,6 @@ USA.
                (string-set! buffer i char)
                (loop (fix:1+ i))))))))
 \f
-;;  General version.
-;;
-;; . This version will uncompress any input that can be read a character at
-;;   a time by applying parameter READ-CHAR to INPUT-PORT.  These do not
-;;   necesarily have to be a port and a port operation, but that is
-;;   the expected use.
-;; . The EOF indicator returned by READ-CHAR must not be a character, which
-;;   implies that EOF-OBJECT? and CHAR? are disjoint.
-
-#|
-(define (uncompress-kernel-by-chars input-port output-port buffer-size
-                                   read-char)
-  (let ((buffer (make-string buffer-size))
-       (cp-table (make-vector window-size)))
-
-    (define (displacement->cp-index displacement cp)
-      (let ((index (fix:- cp displacement)))
-       (if (fix:< index 0) (fix:+ window-size index) index)))
-
-    (define-integrable (cp:+ cp n)
-      (fix:remainder (fix:+ cp n) window-size))
-
-    (define-integrable (read-substring! start end)
-      (let loop ((i start))
-       (if (fix:>= i end)
-           (fix:- i start)
-           (begin
-             (string-set! buffer i (read-char input-port))
-             (loop (fix:1+ i))))))
-
-    (define (grow-buffer!)
-      (let* ((new-size (fix:+ buffer-size (fix:quotient buffer-size 4)))
-            (nbuffer (make-string new-size)))
-       (substring-move! buffer 0 buffer-size nbuffer 0)
-       (set! buffer-size new-size)
-       (set! buffer nbuffer)
-       unspecific))
-
-    (define-integrable (guarantee-buffer nbp)
-      (if (fix:> nbp buffer-size)
-         (grow-buffer!)))
-
-    (let loop ((bp 0) (cp 0))
-      (let ((char (read-char input-port)))
-       (if (not (char? char))          ; Assume EOF
-           (begin
-             (output-port/write-substring output-port buffer 0 bp)
-             bp)
-           (let ((byte (char->integer char)))
-             (if (fix:< byte 16)
-                 (let ((length (fix:+ byte 1)))
-                   (let ((nbp (fix:+ bp length))
-                         (ncp (cp:+ cp length)))
-                     (guarantee-buffer nbp)
-                     (read-substring! bp nbp)
-                     (do ((bp bp (fix:+ bp 1)) (cp cp (cp:+ cp 1)))
-                         ((fix:= bp nbp))
-                       (vector-set! cp-table cp bp))
-                     (loop nbp ncp)))
-                 (let ((cpi (displacement->cp-index
-                             (fix:+ (fix:* (fix:remainder byte 16) 256)
-                                    (char->integer (read-char input-port)))
-                             cp))
-                       (length (fix:+ (fix:quotient byte 16) 1)))
-                   (let ((bp* (vector-ref cp-table cpi))
-                         (nbp (fix:+ bp length))
-                         (ncp (cp:+ cp 1)))
-                     (guarantee-buffer nbp)
-                     (let ((end-bp* (fix:+ bp* length)))
-                       (do ((bp* bp* (fix:+ bp* 1))
-                            (bp bp (fix:+ bp 1)))
-                           ((not (fix:< bp* end-bp*)))
-                         (vector-8b-set! buffer bp
-                                         (vector-8b-ref buffer bp*))))
-                     (vector-set! cp-table cp bp)
-                     (loop nbp ncp))))))))))
-|#
-\f
 ;; This version will uncompress any input that can be read in chunks by
 ;; applying parameter READ-SUBSTRING to INPUT-PORT and a substring
 ;; reference.  These do not necesarily have to be a port and a port
@@ -680,10 +598,8 @@ USA.
 
 (define (compressed-loader uncompressed-type)
   (lambda (compressed-file)
-    (lookup-uncompressed-file compressed-file fasload-loader
-      (lambda ()
-       (let ((load-compressed
-              (lambda (temporary-file)
+    (call-with-temporary-file-pathname
+     (lambda (temporary-file)
                 (call-with-current-continuation
                  (lambda (k)
                    (uncompress-internal compressed-file
@@ -691,38 +607,7 @@ USA.
                                         (lambda (message . irritants)
                                           message irritants
                                           (k #f)))
-                   (fasload-loader temporary-file))))))
-         (case *save-uncompressed-files?*
-           ((#F)
-            (call-with-temporary-file-pathname load-compressed))
-           ((AUTOMATIC)
-            (call-with-uncompressed-file-pathname compressed-file
-                                                  load-compressed))
-           (else
-            (call-with-temporary-file-pathname
-             (lambda (temporary-file)
-               (let ((result (load-compressed temporary-file))
-                     (uncompressed-file
-                      (pathname-new-type compressed-file uncompressed-type)))
-                 (delete-file-no-errors uncompressed-file)
-                 (if (call-with-current-continuation
-                      (lambda (k)
-                        (bind-condition-handler
-                            (list condition-type:file-error
-                                  condition-type:port-error)
-                            (lambda (condition) condition (k #t))
-                          (lambda ()
-                            (rename-file temporary-file uncompressed-file)
-                            #f))))
-                     (call-with-current-continuation
-                      (lambda (k)
-                        (bind-condition-handler
-                            (list condition-type:file-error
-                                  condition-type:port-error)
-                            (lambda (condition) condition (k unspecific))
-                          (lambda ()
-                            (copy-file temporary-file uncompressed-file))))))
-                 result))))))))))
+                   (fasload-loader temporary-file)))))))
 
 (define (uncompress-internal ifile ofile if-fail)
   (call-with-binary-input-file (merge-pathnames ifile)
@@ -738,81 +623,4 @@ USA.
            (call-with-binary-output-file (merge-pathnames ofile)
              (lambda (output)
                (uncompress-ports input output (fix:* (file-length ifile) 2))))
-           (if-fail "Not a recognized compressed file:" ifile))))))
-\f
-(define (lookup-uncompressed-file compressed-file if-found if-not-found)
-  (dynamic-wind
-   (lambda ()
-     (set-car! uncompressed-files (+ (car uncompressed-files) 1)))
-   (lambda ()
-     (let loop ((entries (cdr uncompressed-files)))
-       (cond ((null? entries)
-             (if-not-found))
-            ((and (pathname=? (caar entries) compressed-file)
-                  (cddar entries)
-                  (or (file-modification-time<? compressed-file
-                                                (cadar entries))
-                      (begin
-                        (set-cdr! (cdar entries) #f)
-                        #f)))
-             (dynamic-wind
-              (lambda () unspecific)
-              (lambda ()
-                (or (if-found (cadar entries))
-                    (begin
-                      (set-cdr! (cdar entries) #f)
-                      (loop (cdr entries)))))
-              (lambda ()
-                (if (cddar entries)
-                    (set-cdr! (cdar entries) (real-time-clock))))))
-            (else
-             (loop (cdr entries))))))
-   (lambda ()
-     (set-car! uncompressed-files (- (car uncompressed-files) 1)))))
-
-(define (call-with-uncompressed-file-pathname compressed-file receiver)
-  (let ((temporary-file (temporary-file-pathname)))
-    (let ((entry
-          (cons compressed-file
-                (cons temporary-file (real-time-clock)))))
-      (dynamic-wind
-       (lambda () unspecific)
-       (lambda ()
-        (let ((value (receiver temporary-file)))
-          (without-interrupts
-           (lambda ()
-             (set-cdr! uncompressed-files
-                       (cons entry (cdr uncompressed-files)))))
-          value))
-       (lambda ()
-        (set-cdr! (cdr entry) (real-time-clock)))))))
-
-(define (delete-uncompressed-files!)
-  (do ((entries (cdr uncompressed-files) (cdr entries)))
-      ((null? entries) unspecific)
-    (deallocate-temporary-file (cadar entries))))
-
-(define (clean-uncompressed-files!)
-  (if (= 0 (car uncompressed-files))
-      (let ((time (real-time-clock)))
-       (let loop
-           ((entries (cdr uncompressed-files))
-            (prev uncompressed-files))
-         (if (not (null? entries))
-             (if (or (not (cddar entries))
-                     (< (- time (cddar entries))
-                        *uncompressed-file-lifetime*))
-                 (loop (cdr entries) entries)
-                 (begin
-                   (set-cdr! prev (cdr entries))
-                   (set-cdr! (cdar entries) #f)
-                   (deallocate-temporary-file (cadar entries))
-                   (loop (cdr entries) prev))))))))
-
-(define (initialize-uncompressed-files!)
-  (set! uncompressed-files (list 0))
-  unspecific)
-
-(define *save-uncompressed-files?* 'AUTOMATIC)
-(define *uncompressed-file-lifetime* 300000)
-(define uncompressed-files)
\ No newline at end of file
+           (if-fail "Not a recognized compressed file:" ifile))))))
\ No newline at end of file
index b042811e1ad7921c5a37634902c93c59636dc3fb..930127b99dc729afcd14b1cc104dd6f74690b96c 100644 (file)
@@ -1317,8 +1317,6 @@ USA.
   (files "infstr" "infutl")
   (parent (runtime))
   (export ()
-         *save-uncompressed-files?*
-         *uncompressed-file-lifetime*
          compiled-code-block/filename-and-index
          compiled-entry/filename-and-index
          compiled-entry/block