[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

CLOS Caches Clash



The following patch fixes a bug in Victoria Day PCL (sorry we're still
using it).  Running generic functions in parallel process could let
use the same cache.  Rainy PCL puts WITHOUT-INTERRUPTS around the
equivalent pieces of code.  This code uses SI:STORE-CONDITIONAL which
is machine specific but much nicer.  Perhaps PCL should provide
something like it for those implementations who can handle it.

k


;;; Accessing the cache cache must be atomic.
;;; PCL should have a STORE-CONDITIONAL function defined in LOW.LISP
(defun get-generic-function-cache (size)
  (let* ((expt (floor (log size 2)))
	 (thread (* expt 2))
	 (count (1+ thread))
	 (existing nil))
    (when (>= count (array-dimension *free-generic-function-caches* 0) 2)
      (error "Generic function cache of unprecedented size returned."))
    (setq existing (svref *free-generic-function-caches* thread))
    (cond ((null existing)
	   (incf (svref *free-generic-function-caches* count))
	   (make-generic-function-cache size))
	  ((SI:STORE-CONDITIONAL
	     (SCL:LOCF(svref *free-generic-function-caches* thread))
				 existing (svref existing 0))
	   (flush-generic-function-caches-internal existing)
	   existing)
	  (T (GET-GENERIC-FUNCTION-CACHE SIZE)))))	; Try again

(defun free-generic-function-cache (cache)
  (let* ((size (array-dimension cache 0))
	 (expt (floor (log size 2)))
	 (thread (* expt 2))
	 (count (1+ thread)))
    (when (>= count (array-dimension *free-generic-function-caches* 0) 2)
      (error "Generic function cache of unprecedented size returned."))
    (setf (svref cache 0) (svref *free-generic-function-caches* thread))
    (OR (SI:STORE-CONDITIONAL
	  (SI:LOCF (SVREF *FREE-GENERIC-FUNCTION-CACHES* THREAD))
	  (SVREF *FREE-GENERIC-FUNCTION-CACHES* THREAD) 
	  CACHE)
	(FREE-GENERIC-FUNCTION-CACHE CACHE))))	; Try again