~ chicken-core (master) /tests/test-finalizers-2.scm
Trap1;;;; test-finalizers-2.scm - test finalizers + GC roots23(import (chicken gc) (chicken fixnum))45(define (list-tabulate n proc)6 (let loop ((i 0))7 (if (fx>= i n)8 '()9 (cons (proc i) (loop (fx+ i 1))))))1011(define *n* 1000)12(define *count* 0)1314#>15static void *16makef(int f, C_word x)17{18 void *r = f ? CHICKEN_new_finalizable_gc_root() : CHICKEN_new_gc_root();1920 CHICKEN_gc_root_set(r, x);21 return r;22}2324static void25freef(void *r)26{27 CHICKEN_delete_gc_root(r);28}29<#303132(define makef (foreign-lambda c-pointer "makef" bool scheme-object))33(define freef (foreign-lambda void "freef" c-pointer))3435(define ((fin f e) x)36 (set! *count* (add1 *count*))37 (assert ((if e even? odd?) (car x)))38 (when e (freef f)))3940(print "creating gc roots")4142(let* ((x (list-tabulate *n* list))43 (fs (list-tabulate *n* (lambda (x) (zero? (modulo x 2)))))44 (rs (map makef fs x)))45 (for-each46 (lambda (x f e)47 (set-finalizer! x (fin f e)))48 x rs fs)49 (print "forcing finalizers")50 (##sys#force-finalizers)51 (assert (zero? *count*))52 (print "dropping data")53 (set! x #f)54 (print "forcing finalizables")55 (##sys#force-finalizers)56 (print *count*)57 (assert (= (quotient *n* 2) *count*))58 (print "releasing non-finalizable gc roots")59 (for-each60 (lambda (f e)61 (unless e (freef f)))62 rs fs)63 (print "forcing remaining")64 (##sys#force-finalizers)65 (assert (= *n* *count*)))6667;;; new finalizer API6869(define c1 (list *count*))70(define f1 (make-finalizer c1))71(add-to-finalizer f1 (make-vector 10))72(define f2 (make-finalizer f1))73(gc #t)74(assert (vector? (f1)))75(assert (not (f1)))76(set! c1 #f)77(gc #t)78(assert (equal? (f1) (list *count*)))79(assert (not (f1)))80(set! f1 #f)81(gc #t)82(assert (procedure? (f2)))83(assert (not (f2)))