id,summary,reporter,owner,description,type,status,priority,milestone,component,version,resolution,keywords,cc,difficulty 1586,Context-switch from GC causes infinite GC loop,megane,,"The following code causes the runtime to enter an infinite GC loop. With help of Christian and Kon the cause was determined to be a re-entry to the GC while GC'ing. In the example below the thread running a finalizer runs out of its quantum while running `spin` and does a context switch. The other thread then starts a new GC which causes the issue. Using `disable-interrupts` makes the issue go away. I haven't tested if `disable-interrupts` is enough if the finalizer calls something that was compiled without `disable-interrupts`. I'll attach a fuzzer that can be used instead if the example doesn't work. {{{ ;; (declare (disable-interrupts)) (cond-expand (chicken-5 (import (chicken base)) (import (chicken gc)) (import (srfi 18))) (else (use srfi-18))) (define (spin count) (let lp2 ([i 0]) (when (< i count) (lp2 (add1 i))))) (define (add-finalized) (set-finalizer! (list 'foo) (lambda (o) (spin 100)))) (let lp ([i 0]) (while (< i 100) (print* i "" "") (let ([threads (list (make-thread (lambda () (add-finalized) (add-finalized) (gc #t) (add-finalized) (add-finalized) (add-finalized)) ""thread-a"") (make-thread (lambda () (gc #t) (add-finalized) (add-finalized)) ""thread-b""))]) (for-each thread-start! threads) (for-each thread-join! threads)) (lp (add1 i)))) (print ""dones"") ;; Output: ;; $ csc gcloop2.scm && ./gcloop2 ;; 0 1 2 3 4 5 6 7 8 9 10 11 12 }}} ",defect,closed,major,5.2,compiler,5.0.0,fixed,garbage collector context-switch threads scheduler,,insane