X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fgc.lisp;h=7ba3b3b3e05f7e3a2e50819992006df7b7018cec;hb=7a0f4c68d94ff6c9a54c7605b6fd3cd8125c1c8c;hp=c0c7b022b84775acbccbaff7dbbeb2ff4cd8c2a8;hpb=96a5ccbf2930180fbcfae8d286acbd7416b00af8;p=sbcl.git diff --git a/src/code/gc.lisp b/src/code/gc.lisp index c0c7b02..7ba3b3b 100644 --- a/src/code/gc.lisp +++ b/src/code/gc.lisp @@ -180,9 +180,25 @@ run in any thread.") (defvar *already-in-gc* (sb!thread:make-mutex :name "GC lock") "ID of thread running SUB-GC") +;;; A unique GC id. This is supplied for code that needs to detect +;;; whether a GC has happened since some earlier point in time. For +;;; example: +;;; +;;; (let ((epoch *gc-epoch*)) +;;; ... +;;; (unless (eql epoch *gc-epoch) +;;; ....)) +;;; +;;; This isn't just a fixnum counter since then we'd have theoretical +;;; problems when exactly 2^29 GCs happen between epoch +;;; comparisons. Unlikely, but the cost of using a cons instead is too +;;; small to measure. -- JES, 2007-09-30 +(declaim (type cons *gc-epoch*)) +(defvar *gc-epoch* (cons nil nil)) + (defun sub-gc (&key (gen 0)) (unless (eq sb!thread:*current-thread* - (sb!thread::mutex-value *already-in-gc*)) + (sb!thread:mutex-value *already-in-gc*)) ;; With gencgc, unless *GC-PENDING* every allocation in this ;; function triggers another gc, potentially exceeding maximum ;; interrupt nesting. If *GC-INHIBIT* is not true, however, @@ -202,6 +218,7 @@ run in any thread.") (gc-stop-the-world) (let ((start-time (get-internal-run-time))) (collect-garbage gen) + (setf *gc-epoch* (cons nil nil)) (incf *gc-run-time* (- (get-internal-run-time) start-time))) (setf *gc-pending* nil @@ -252,6 +269,9 @@ run in any thread.") ;; as having these cons more then we have space left leads to huge ;; badness. (scrub-control-stack) + ;; Power cache of the bignum printer: drops overly large bignums and + ;; removes duplicate entries. + (scrub-power-cache) ;; FIXME: CTYPE-OF-CACHE-CLEAR isn't thread-safe. #!-sb-thread (ctype-of-cache-clear))