0.8pre.2
[sbcl.git] / src / pcl / cache.lisp
index c3be109..fc92326 100644 (file)
   `(cache-vector-ref ,cache-vector 0))
 
 (defun flush-cache-vector-internal (cache-vector)
-  (sb-sys:without-interrupts
+  (with-pcl-lock
     (fill (the simple-vector cache-vector) nil)
     (setf (cache-vector-lock-count cache-vector) 0))
   cache-vector)
 
 (defmacro modify-cache (cache-vector &body body)
-  `(sb-sys:without-interrupts
+  `(with-pcl-lock
      (multiple-value-prog1
        (progn ,@body)
        (let ((old-count (cache-vector-lock-count ,cache-vector)))
 (defmacro cache-lock-count (cache)
   `(cache-vector-lock-count (cache-vector ,cache)))
 \f
-;;; some facilities for allocation and freeing caches as they are needed
-
-;;; This is done on the assumption that a better port of PCL will
-;;; arrange to cons these all in the same static area. Given that, the
-;;; fact that PCL tries to reuse them should be a win.
-
-(defvar *free-cache-vectors* (make-hash-table :size 16 :test 'eql))
-
 ;;; Return a cache that has had FLUSH-CACHE-VECTOR-INTERNAL called on
 ;;; it. This returns a cache of exactly the size requested, it won't
 ;;; ever return a larger cache.
 (defun get-cache-vector (size)
-  (let ((entry (gethash size *free-cache-vectors*)))
-    (sb-sys:without-interrupts
-      (cond ((null entry)
-            (setf (gethash size *free-cache-vectors*) (cons 0 nil))
-            (get-cache-vector size))
-           ((null (cdr entry))
-            (incf (car entry))
-            (flush-cache-vector-internal (allocate-cache-vector size)))
-           (t
-            (let ((cache (cdr entry)))
-              (setf (cdr entry) (cache-vector-ref cache 0))
-              (flush-cache-vector-internal cache)))))))
-
-(defun free-cache-vector (cache-vector)
-  (let ((entry (gethash (cache-vector-size cache-vector) *free-cache-vectors*)))
-    (sb-sys:without-interrupts
-      (if (null entry)
-         (error
-          "attempt to free a cache-vector not allocated by GET-CACHE-VECTOR")
-         (let ((thread (cdr entry)))
-           (loop (unless thread (return))
-                 (when (eq thread cache-vector)
-                   (error "freeing a cache twice"))
-                 (setq thread (cache-vector-ref thread 0)))
-           (flush-cache-vector-internal cache-vector) ; to help the GC
-           (setf (cache-vector-ref cache-vector 0) (cdr entry))
-           (setf (cdr entry) cache-vector)
-           nil)))))
-
-;;; This is just for debugging and analysis. It shows the state of the
-;;; free cache resource.
-#+sb-show
-(defun show-free-cache-vectors ()
-  (let ((elements ()))
-    (maphash (lambda (s e) (push (list s e) elements)) *free-cache-vectors*)
-    (setq elements (sort elements #'< :key #'car))
-    (dolist (e elements)
-      (let* ((size (car e))
-            (entry (cadr e))
-            (allocated (car entry))
-            (head (cdr entry))
-            (free 0))
-       (loop (when (null head) (return t))
-             (setq head (cache-vector-ref head 0))
-             (incf free))
-       (format t
-               "~&There are  ~4D caches of size  ~4D. (~D free  ~3D%)"
-               allocated
-               size
-               free
-               (floor (* 100 (/ free (float allocated)))))))))
+  (flush-cache-vector-internal (make-array size)))
+  
 \f
 ;;;; wrapper cache numbers
 
   (when (invalid-wrapper-p (layout-of instance))
     (check-wrapper-validity instance)))
 \f
-(defvar *free-caches* nil)
 
 (defun get-cache (nkeys valuep limit-fn nlines)
-  (let ((cache (or (sb-sys:without-interrupts (pop *free-caches*))
-                   (make-cache))))
+  (let ((cache (make-cache)))
     (declare (type cache cache))
     (multiple-value-bind (cache-mask actual-size line-size nlines)
        (compute-cache-parameters nkeys valuep nlines)
                             &optional (new-field +first-wrapper-cache-number-index+))
   (let ((nkeys (cache-nkeys old-cache))
        (valuep (cache-valuep old-cache))
-       (cache (or (sb-sys:without-interrupts (pop *free-caches*))
-                   (make-cache))))
+       (cache (make-cache)))
     (declare (type cache cache))
     (multiple-value-bind (cache-mask actual-size line-size nlines)
        (if (= new-nlines (cache-nlines old-cache))
     (setf (cache-vector new-cache) new-vector)
     new-cache))
 
-(defun free-cache (cache)
-  (free-cache-vector (cache-vector cache))
-  (setf (cache-vector cache) #())
-  (setf (cache-owner cache) nil)
-  (push cache *free-caches*)
-  nil)
-
 (defun compute-line-size (x)
   (power-of-two-ceiling x))
 
 ;;; nice property of throwing out any entries that are invalid.
 (defvar *cache-expand-threshold* 1.25)
 
-(defun fill-cache (cache wrappers value &optional free-cache-p)
-
+(defun fill-cache (cache wrappers value)
   ;; FILL-CACHE won't return if WRAPPERS is nil, might as well check..
-  (unless wrappers
-    (error "fill-cache: WRAPPERS arg is NIL!"))
+  (assert wrappers)
 
   (or (fill-cache-p nil cache wrappers value)
       (and (< (ceiling (* (cache-count cache) 1.25))
              (if (= (cache-nkeys cache) 1)
                  (1- (cache-nlines cache))
                  (cache-nlines cache)))
-          (adjust-cache cache wrappers value free-cache-p))
-      (expand-cache cache wrappers value free-cache-p)))
+          (adjust-cache cache wrappers value))
+      (expand-cache cache wrappers value)))
 
 (defvar *check-cache-p* nil)
 
 ;;; If this returns NIL, it means that it wasn't possible to find a
 ;;; wrapper field for which all of the entries could be put in the
 ;;; cache (within the limit).
-(defun adjust-cache (cache wrappers value free-old-cache-p)
+(defun adjust-cache (cache wrappers value)
   (with-local-cache-functions (cache)
     (let ((ncache (get-cache-from-cache cache (nlines) (field))))
-      (do ((nfield (cache-field ncache) (next-wrapper-cache-number-index nfield)))
-         ((null nfield) (free-cache ncache) nil)
+      (do ((nfield (cache-field ncache)
+                  (next-wrapper-cache-number-index nfield)))
+         ((null nfield) nil)
        (setf (cache-field ncache) nfield)
        (labels ((try-one-fill-from-line (line)
                   (fill-cache-from-cache-p nil ncache cache line))
                     (unless (try-one-fill (car wrappers+value) (cdr wrappers+value))
                       (return nil)))
                   (try-one-fill wrappers value))
-             (progn (when free-old-cache-p (free-cache cache))
-                    (return (maybe-check-cache ncache)))
+             (return (maybe-check-cache ncache))
              (flush-cache-vector-internal (cache-vector ncache))))))))
 
 ;;; returns: (values <cache>)
-(defun expand-cache (cache wrappers value free-old-cache-p)
+(defun expand-cache (cache wrappers value)
   ;;(declare (values cache))
   (with-local-cache-functions (cache)
     (let ((ncache (get-cache-from-cache cache (* (nlines) 2))))
                 (unless (fill-cache-from-cache-p nil ncache cache line)
                   (do-one-fill (line-wrappers line) (line-value line))))
               (do-one-fill (wrappers value)
-                (setq ncache (or (adjust-cache ncache wrappers value t)
+                (setq ncache (or (adjust-cache ncache wrappers value)
                                  (fill-cache-p t ncache wrappers value))))
               (try-one-fill (wrappers value)
                 (fill-cache-p nil ncache wrappers value)))
            (do-one-fill (car wrappers+value) (cdr wrappers+value))))
        (unless (try-one-fill wrappers value)
          (do-one-fill wrappers value))
-       (when free-old-cache-p (free-cache cache))
        (maybe-check-cache ncache)))))
 \f
 ;;; This is the heart of the cache filling mechanism. It implements