Remove without-interrupts from runtime/queue.scm.
authorMatt Birkholz <puck@birchwood-abbey.net>
Fri, 19 Jun 2015 20:04:04 +0000 (13:04 -0700)
committerMatt Birkholz <puck@birchwood-abbey.net>
Mon, 6 Jul 2015 05:45:45 +0000 (22:45 -0700)
Add make-serial-queue and use it in runtime globals: the event
distributors, GC daemons and REPLs.  Note that the "safe" queue
operations, when applied to non-serializing queues in SMPing worlds,
are NOT thread-safe.  This only happens in LIAR, SWAT, Edwin, X11
Graphics and OS2 Graphics -- single-threaded applications.

src/runtime/events.scm
src/runtime/gcdemn.scm
src/runtime/poplat.scm
src/runtime/prop1d.scm
src/runtime/queue.scm
src/runtime/rep.scm
src/runtime/runtime.pkg

index 6be93e1fd9c71b754512d73300cccd4a12b48ef4..691842c95a0818ead6804e67d7dd70d06fd0764e 100644 (file)
@@ -37,7 +37,7 @@ USA.
 (define-structure (event-distributor
                   (constructor make-event-distributor ())
                   (conc-name event-distributor/))
-  (events (make-queue))
+  (events (make-serial-queue))
   (lock false)
   (receivers '()))
 
index 12e0e95d572c82d0cec20909e0743028457269b7..2739c263f292221633724741aee43c361442a620 100644 (file)
@@ -30,15 +30,20 @@ USA.
 (declare (usual-integrations))
 \f
 (define (initialize-package!)
-  (set! primitive-gc-daemons (make-queue))
+  (set! primitive-gc-daemons (make-serial-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! add-primitive-gc-daemon!/unsafe
+       (make-adder/unsafe primitive-gc-daemons))
+  (set! gc-daemons (make-serial-queue))
   (set! trigger-gc-daemons! (make-trigger gc-daemons))
   (set! add-gc-daemon! (make-adder gc-daemons))
-  (set! secondary-gc-daemons (make-queue))
+  (set! add-gc-daemon!/unsafe (make-adder/unsafe gc-daemons))
+  (set! secondary-gc-daemons (make-serial-queue))
   (set! trigger-secondary-gc-daemons! (make-trigger secondary-gc-daemons))
   (set! add-secondary-gc-daemon! (make-adder secondary-gc-daemons))
+  (set! add-secondary-gc-daemon!/unsafe
+       (make-adder/unsafe secondary-gc-daemons))
   (let ((fixed-objects ((ucode-primitive get-fixed-objects-vector))))
     (vector-set! fixed-objects #x0B trigger-primitive-gc-daemons!)
     ((ucode-primitive set-fixed-objects-vector!) fixed-objects)))
@@ -49,6 +54,7 @@ USA.
 (define primitive-gc-daemons)
 (define trigger-primitive-gc-daemons!)
 (define add-primitive-gc-daemon!)
+(define add-primitive-gc-daemon!/unsafe)
 
 ;;; GC-DAEMONS are executed after each GC from an interrupt handler.
 ;;; This interrupt handler has lower priority than the GC interrupt,
@@ -58,6 +64,7 @@ USA.
 (define gc-daemons)
 (define trigger-gc-daemons!)
 (define add-gc-daemon!)
+(define add-gc-daemon!/unsafe)
 (define (add-gc-daemon!/no-restore daemon)
   (add-gc-daemon!
    (lambda ()
@@ -70,6 +77,7 @@ USA.
 (define secondary-gc-daemons)
 (define trigger-secondary-gc-daemons!)
 (define add-secondary-gc-daemon!)
+(define add-secondary-gc-daemon!/unsafe)
 
 (define (make-trigger daemons)
   (lambda ()
@@ -80,6 +88,10 @@ USA.
   (lambda (daemon)
     (enqueue! daemons daemon)))
 
+(define (make-adder/unsafe daemons)
+  (lambda (daemon)
+    (enqueue!/unsafe daemons daemon)))
+
 (define (gc-clean #!optional threshold)
   (let ((threshold
         (cond ((default-object? threshold) 100)
index 95dda1184ef469068a5026622ae0d032b75bb5a5..0455f691d6f93ed03dd2d952ea5220d417ae3d5d 100644 (file)
@@ -34,7 +34,7 @@ USA.
 
 (define (initialize-package!)
   (set! population-of-populations (list population-tag (make-thread-mutex)))
-  (add-secondary-gc-daemon! clean-all-populations!))
+  (add-secondary-gc-daemon!/unsafe clean-all-populations!))
 
 (define (initialize-unparser!)
   (unparser/set-tagged-pair-method! population-tag
index e4e9e360fa5b52865ff908348794d888568ce4fe..f61cb46adbfd68d91230c648a92fd3fd60d0d28b 100644 (file)
@@ -31,7 +31,7 @@ USA.
 \f
 (define (initialize-package!)
   (set! population-of-1d-tables (make-serial-population/unsafe))
-  (add-secondary-gc-daemon! clean-1d-tables!))
+  (add-secondary-gc-daemon!/unsafe clean-1d-tables!))
 
 (define (initialize-unparser!)
   (unparser/set-tagged-pair-method! 1d-table-tag
index bf9d0527ac09cbcff7adf5b055e1ce308cbdf25e..5d646b883194af988d944fc43ef1e886ff422d52 100644 (file)
@@ -30,31 +30,34 @@ USA.
 (declare (usual-integrations))
 \f
 (define-integrable (make-queue)
-  (cons '() '()))
+  (cons* #f '() '()))
+
+(define-integrable (make-serial-queue)
+  (cons* (make-thread-mutex) '() '()))
 
 (define-integrable (queue-empty? queue)
-  (not (pair? (car queue))))
+  (not (pair? (cadr queue))))
 
 (define-integrable (queued?/unsafe queue item)
-  (memq item (car queue)))
+  (memq item (cadr queue)))
 
 (define (enqueue!/unsafe queue object)
   (let ((next (cons object '())))
-    (if (pair? (cdr queue))
-       (set-cdr! (cdr queue) next)
-       (set-car! queue next))
-    (set-cdr! queue next)
+    (if (pair? (cddr queue))
+       (set-cdr! (cddr queue) next)
+       (set-car! (cdr queue) next))
+    (set-cdr! (cdr queue) next)
     unspecific))
 
 (define (dequeue!/unsafe queue)
-  (let ((next (car queue)))
+  (let ((next (cadr queue)))
     (if (not (pair? next))
        (error "Attempt to dequeue from empty queue"))
     (if (pair? (cdr next))
-       (set-car! queue (cdr next))
+       (set-car! (cdr queue) (cdr next))
        (begin
-         (set-car! queue '())
-         (set-cdr! queue '())))
+         (set-car! (cdr queue) '())
+         (set-cdr! (cdr queue) '())))
     (car next)))
 
 (define (queue-map!/unsafe queue procedure)
@@ -65,24 +68,33 @@ USA.
          (loop)))))
 
 (define-integrable (queue->list/unsafe queue)
-  (car queue))
+  (cadr queue))
+
+;;; Safe versions of the above operations (when used on a serializing
+;;; queue).
 
-;;; Safe (interrupt locked) versions of the above operations.
+(define-integrable (with-queue-lock queue thunk)
+  (let ((mutex (car queue)))
+    (if mutex
+       (with-thread-mutex-lock mutex
+         (lambda ()
+           (without-interruption thunk)))
+       (without-interruption thunk))))
 
 (define-integrable (queued? queue item)
-  (without-interrupts (lambda () (queued?/unsafe queue item))))
+  (with-queue-lock queue (lambda () (queued?/unsafe queue item))))
 
 (define-integrable (enqueue! queue object)
-  (without-interrupts (lambda () (enqueue!/unsafe queue object))))
+  (with-queue-lock queue (lambda () (enqueue!/unsafe queue object))))
 
 (define-integrable (dequeue! queue)
-  (without-interrupts (lambda () (dequeue!/unsafe queue))))
+  (with-queue-lock queue (lambda () (dequeue!/unsafe queue))))
 
 (define (queue-map! queue procedure)
   (let ((empty (list 'EMPTY)))
     (let loop ()
       (let ((item
-            (without-interrupts
+            (with-queue-lock queue
              (lambda ()
                (if (queue-empty? queue)
                    empty
@@ -93,6 +105,6 @@ USA.
              (loop)))))))
 
 (define (queue->list queue)
-  (without-interrupts
+  (with-queue-lock queue
     (lambda ()
       (list-copy (queue->list/unsafe queue)))))
\ No newline at end of file
index 9ea3cf0ed0684ef3684cbbde11543644406125c0..65c86f072a47764c3ac86725f223464afbe09b1a 100644 (file)
@@ -677,7 +677,7 @@ USA.
   (condition #f read-only #t)
   (reader-history (make-repl-history repl-reader-history-size))
   (printer-history (make-repl-history repl-printer-history-size))
-  (input-queue (make-queue) read-only #t))
+  (input-queue (make-serial-queue) read-only #t))
 
 (define (repl? object)
   (and (cmdl? object)
index 858eea49f3faef907074086ce2aec7551394aa16..a9c0b290badba575ec948271960277fe79534499 100644 (file)
@@ -562,6 +562,7 @@ USA.
   (parent (runtime))
   (export ()
          make-queue
+         make-serial-queue
          queue-empty?
          queued?/unsafe
          enqueue!/unsafe
@@ -1112,6 +1113,8 @@ USA.
   (import (runtime population)
          make-serial-population/unsafe
          add-to-population!/unsafe)
+  (import (runtime gc-daemons)
+         add-secondary-gc-daemon!/unsafe)
   (initialization (initialize-package!)))
 
 (define-package (runtime 2d-property)
@@ -3160,6 +3163,8 @@ USA.
 (define-package (runtime population)
   (files "poplat")
   (parent (runtime))
+  (import (runtime gc-daemons)
+         add-secondary-gc-daemon!/unsafe)
   (export ()
          add-to-population!
          empty-population!