From 29a168e2bf7a6d509dea282cc5c781aba734d87c Mon Sep 17 00:00:00 2001 From: Gabor Melis Date: Mon, 16 Feb 2009 21:37:34 +0000 Subject: [PATCH] 1.0.25.23: more allocation checks - in gencgc alloc() check that we are in pseudo atomic - assert that interrupt_handle_pending does not happen in pseudo atomic - assert that cheneygc pa_alloc() runs with deferrable signals blocked - add test code to trigger gc from pa_alloc to help testing how the runtime deals with such rare events --- src/runtime/alloc.c | 17 +++++++++++++++-- src/runtime/gencgc.c | 1 + src/runtime/interrupt.c | 39 ++++++++++++++++++++++++++++++++------- src/runtime/interrupt.h | 1 + version.lisp-expr | 2 +- 5 files changed, 50 insertions(+), 10 deletions(-) diff --git a/src/runtime/alloc.c b/src/runtime/alloc.c index 3ed1631..4f3be56 100644 --- a/src/runtime/alloc.c +++ b/src/runtime/alloc.c @@ -43,6 +43,16 @@ pa_alloc(int bytes, int page_type_flag) clear_pseudo_atomic_interrupted(th); set_pseudo_atomic_atomic(th); result = general_alloc(bytes, page_type_flag); +#if 0 + /* See how the runtime deals with GC being triggerred. */ + if ((SymbolValue(GC_PENDING,th) == NIL) && + (SymbolValue(GC_INHIBIT,th) == NIL) && + (random() < RAND_MAX/100)) { + SetSymbolValue(GC_PENDING,T,th); + set_pseudo_atomic_interrupted(th); + maybe_save_gc_mask_and_block_deferrables(NULL); + } +#endif clear_pseudo_atomic_atomic(th); if (get_pseudo_atomic_interrupted(th)) { @@ -75,8 +85,11 @@ pa_alloc(int bytes, int page_type_flag) { lispobj *result; - /* FIXME: this is not pseudo atomic at all, but is called only from - * interrupt safe places like interrupt handlers. MG - 2005-08-09 */ + /* This is not pseudo atomic at all, but is called only from + * interrupt safe places like interrupt handlers. MG - + * 2005-08-09 */ + check_deferrables_blocked_or_lose(); + result = dynamic_space_free_pointer; /* Align up to next dual word boundary. */ diff --git a/src/runtime/gencgc.c b/src/runtime/gencgc.c index 9680743..5d687f4 100644 --- a/src/runtime/gencgc.c +++ b/src/runtime/gencgc.c @@ -4771,6 +4771,7 @@ general_alloc(long nbytes, int page_type_flag) lispobj * alloc(long nbytes) { + gc_assert(get_pseudo_atomic_atomic(arch_os_get_current_thread())); return general_alloc(nbytes, BOXED_PAGE_FLAG); } diff --git a/src/runtime/interrupt.c b/src/runtime/interrupt.c index 6824f3b..74fd67b 100644 --- a/src/runtime/interrupt.c +++ b/src/runtime/interrupt.c @@ -74,6 +74,15 @@ static void store_signal_data_for_later (struct interrupt_data *data, siginfo_t *info, os_context_t *context); +static void +fill_current_sigmask(sigset_t *sigset) +{ + /* Get the current sigmask, by blocking the empty set. */ + sigset_t empty; + sigemptyset(&empty); + thread_sigmask(SIG_BLOCK, &empty, sigset); +} + void sigaddset_deferrable(sigset_t *s) { @@ -123,6 +132,28 @@ sigset_t blockable_sigset; #endif void +check_deferrables_blocked_in_sigset_or_lose(sigset_t *sigset) +{ +#if !defined(LISP_FEATURE_WIN32) + int i; + for(i = 1; i < NSIG; i++) { + if (sigismember(&deferrable_sigset, i) && !sigismember(sigset, i)) + lose("deferrable signal %d not blocked\n",i); + } +#endif +} + +void +check_deferrables_blocked_or_lose(void) +{ +#if !defined(LISP_FEATURE_WIN32) + sigset_t current; + fill_current_sigmask(¤t); + check_deferrables_blocked_in_sigset_or_lose(¤t); +#endif +} + +void check_blockables_blocked_or_lose(void) { #if !defined(LISP_FEATURE_WIN32) @@ -407,14 +438,8 @@ interrupt_handle_pending(os_context_t *context) struct thread *thread; - /* Punt if in PA section, marking it as interrupted. This can - * happenat least if we pick up a GC request while in a - * WITHOUT-GCING with an outer PA -- it is not immediately clear - * to me that this should/could ever happen, but better safe then - * sorry. --NS 2007-05-15 */ if (arch_pseudo_atomic_atomic(context)) { - arch_set_pseudo_atomic_interrupted(context); - return; + lose("Handling pending interrupt in pseduo atomic."); } thread = arch_os_get_current_thread(); diff --git a/src/runtime/interrupt.h b/src/runtime/interrupt.h index 09a63f2..579eeb6 100644 --- a/src/runtime/interrupt.h +++ b/src/runtime/interrupt.h @@ -29,6 +29,7 @@ extern sigset_t deferrable_sigset; extern sigset_t blockable_sigset; +extern void check_deferrables_blocked_or_lose(void); extern void check_blockables_blocked_or_lose(void); extern void check_gc_signals_unblocked_or_lose(void); extern void unblock_gc_signals(void); diff --git a/version.lisp-expr b/version.lisp-expr index 4016edd..7861267 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"1.0.25.22" +"1.0.25.23" -- 1.7.10.4