sbcl-devel

* triggerring gc
As the code uses something like:
if(!data->pending_handler) maybe_defer_handler(interrupt_maybe_gc_int,...)
triggerring gc is not reliable especially under heavy interrupt load (read:=
=20
sb-sprof). Furthermore, in a WITHOUT-INTERRUPTS gc is not triggered, becaus=
e=20
maybe_defer_handler defers it.
* delivery of SIG_STOP_FOR_GC
In a WITHOUT-INTERRUPTS block this signal is deferred, thus the gc cannot=20
start until an exit from it.
* WITHOUT-GCING
Thread A can already be stopping the world when thread B enters the=20
WITHOUT-GCING body and since the SIG_STOP_FOR_GC is not blocked thread B is=
=20
stopped and gc starts.
Assuming these are undesirable (including WITHOUT-INTERRUPTS deferring gc (=
?))=20
my current plan is to add gc_pending, sig_stop_for_gc_pending fields to=20
interrupt_data and:
=2D make WITHOUT-INTERRUPTS let gcs and SIG_STOP_FOR_GCs through
=2D make WITHOUT-GCING and pseudo atomic block/defer SIG_STOP_FOR_GC
=2D give priority to gc over signal handling (?!), if there is an interrupt=
and=20
a gc/SIG_STOP_FOR_GC pending do the gc first
Currently, I'm reading up on the fabulous and rich history of gencgc.c, but=
in=20
the meantime let me know if you have a simple(r) scheme for this.
Cheers, G=E1bor

Another 40k< patch: http://retes.hu/~mega/gc-trigger.patch
As always, it is fairly risky to change the interrupt handling code so
here it is for your review and testing pleasure. It is tested on
x86-linux with{/,out} threads and ppc-darwin.
* implementation changes
The *NEED-TO-COLLECT-GARBAGE* special is gone. A similar - but
per-thread - special: *GC-PENDING* is here. It is set by both gencgc
and cheneygc trigger.
In threaded builds SIG_STOP_FOR_GC is no longer deferrable by the
normal deferral mechanism and rules. It is only deferred in pseudo
atomic sections and when *GC-INHIBIT*. There is another
per-thread special for this purpose: *STOP-FOR-GC-PENDING*.
Whenever *GC-INHI-BIT* is cleared (either by a GC-ON or when exiting
a WITHOUT-GCING) the pending gc or the signal handler is run:
(when (and (not *gc-inhibit*)
(or #!+sb-thread *stop-for-gc-pending*
*gc-pending*))
(sb!unix::receive-pending-interrupt))
On the receiving side interrupt_handle_pending is made clever enough
not to run pending handlers whose time has not come (i.e. in a
WITHOUT-INTERRUPTS it only does gc and leaves the pending handlers
alone).
* the bugs fixed
** WITHOUT-INTERRUPTS no longer blocks gc from the current or other
threads.
** WITHOUT-GCING on the other hand correctly defers gc, be it
automatically triggered or explicitly called, and SIG_STOP_FOR_GC.
** GC-{ON,OFF} now work within WITHOUT-GCING, too
** the gc trigger is more reliable as it does not share the
interrupt deferral mechanism, most notably sb-sprof does not make
triggering gc any harder