This patch limits the number of available finalizers (currently to 4096) and removes the dynamic resizing of the "pending finalizers vector", which is IMHO the cause of crashes when finalizers are created excessively. Contrary to an earlier e-mail I do now think that this problem needs to be fixed right now and should not be postponed to a later release (and I do not see any other solution in the moment).
Since the interaction between allocation, GC, compiler-optimization, hardware platform, ABI and finalization is so interdepedent that it is effectively non-deterministic, I do not claim that the problems that occur with mass-finalization are solved - on the other hand I tested the example in #866 as well as the trivial finalizer-allocating loop and could not reproduce crashes, regardless of nursery-settings and optimization flags. User programs can override the finalizer limit using the "-:f" runtime option if a large number of finalizations are expected or required in specific applications. cheers, felix
>From ae06c61181d975d8a730c75253e0312aa5681b96 Mon Sep 17 00:00:00 2001 From: felix <[email protected]> Date: Fri, 22 Jun 2012 17:31:19 +0200 Subject: [PATCH] Make the maximum number of finalizers a fixed limit (currently 4096). The dynamic resizing of the "pending finalizers vector" (##sys#pending-finalizers) appears to expose a race-condition with the garbage collector when finalizers are created and excecuted exccessively. The exact details are unknown but this bottleneck is not explicitly handled (concurrent access of the PFV from the collector and runtime code for creating and processing finalizers). Reported by "megane". A test-case provided by him has been added to the test-suite. This patch fixes #866. --- chicken.h | 1 - library.scm | 19 +++++++------------ runtime.c | 14 -------------- 3 files changed, 7 insertions(+), 27 deletions(-) diff --git a/chicken.h b/chicken.h index 837a51c..62dd1bc 100644 --- a/chicken.h +++ b/chicken.h @@ -1563,7 +1563,6 @@ C_fctexport void C_fcall C_paranoid_check_for_interrupt(void) C_regparm; C_fctexport void C_zap_strings(C_word str); C_fctexport void C_set_or_change_heap_size(C_word heap, int reintern); C_fctexport void C_do_resize_stack(C_word stack); -C_fctexport C_word C_resize_pending_finalizers(C_word size); C_fctexport void C_initialize_lf(C_word *lf, int count); C_fctexport void *C_register_lf(C_word *lf, int count); C_fctexport void *C_register_lf2(C_word *lf, int count, C_PTABLE_ENTRY *ptable); diff --git a/library.scm b/library.scm index 030fad8..5484c47 100644 --- a/library.scm +++ b/library.scm @@ -4574,18 +4574,13 @@ EOF (define set-finalizer! (lambda (x y) (when (fx> (##sys#fudge 26) _max_pending_finalizers) - (if (##core#inline "C_resize_pending_finalizers" (fx* 2 _max_pending_finalizers)) - (begin - (set! ##sys#pending-finalizers (##sys#grow-vector ##sys#pending-finalizers - (fx+ (fx* 2 _max_pending_finalizers) 1) - (##core#undefined))) - (when (##sys#fudge 13) - (print "[debug] too many finalizers (" (##sys#fudge 26) - "), resized max finalizers to " _max_pending_finalizers "...") ) ) - (begin - (when (##sys#fudge 13) - (print "[debug] too many finalizers (" (##sys#fudge 26) "), forcing ...") ) - (##sys#force-finalizers) ) ) ) + (when (##sys#fudge 13) + (print "[debug] too many finalizers (" (##sys#fudge 26) "), forcing ...") ) + (##sys#force-finalizers) + (when (fx> (##sys#fudge 26) _max_pending_finalizers) + (##sys#signal-hook + #:memory-error 'set-finalizer! + "maximal finalizer-count exceeded"))) (##sys#set-finalizer! x y) ) ) (define ##sys#run-pending-finalizers diff --git a/runtime.c b/runtime.c index b0ccc85..69ee5d8 100644 --- a/runtime.c +++ b/runtime.c @@ -1108,20 +1108,6 @@ void C_check_nursery_minimum(C_word words) panic(C_text("nursery is too small - try higher setting using the `-:s' option")); } -C_word C_resize_pending_finalizers(C_word size) { - int sz = C_num_to_int(size); - - FINALIZER_NODE **newmem = - (FINALIZER_NODE **)C_realloc(pending_finalizer_indices, sz * sizeof(FINALIZER_NODE *)); - - if (newmem == NULL) - return C_SCHEME_FALSE; - - pending_finalizer_indices = newmem; - C_max_pending_finalizers = sz; - return C_SCHEME_TRUE; -} - /* Parse runtime options from command-line: */ -- 1.6.0.4
_______________________________________________ Chicken-hackers mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/chicken-hackers
