[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

GC-DEFER, GC-RESTART, and friends



CC: (BUG LISPM) at MIT-MC

Here's an idea I came up with in discussion with RLB the other day about
gc's and code that requires knowing when one happens ... there are times
when you worry about doing a given task not because it is particularly
tricky or that you can't start it over but just 'cuz it's prone to
timing screws. Wouldn't it be nice if code of that point could just say
-- start me over here if you have to GC ... So you could do

  (GC-RESTART
    (SETQ FOO (MUNKAM x))
    ... simple code involving FOO's value ...)

where you aren't going to do anything to make the garbage collector get
up and do its thing, but you don't have to lock out interrupts to keep things\n from getting messed up ... 

Naturally, there's a new idiom for doing infinite loops ... people might want
to replace
		(DO () (NIL) ...) with (GC-RESTART ... (GC))

yes, some silly things can be made out of it, but there are useful applications
too ... Doing pointer arithmetic would be a whole lot simpler if one could
do this sort of thing... I think this can open code into something pretty
efficient if you just keep a location around which if non-zero contains
info about what state to return to if a GC occurs.... but there is this
hairy case... if one does

	(GC-RESTART ... (GC-RESTART ... x ...) ...),

it seems to me that one has to return to the outer GC-RESTART but one
still may or may not want to run the inner code as well ... eg, suppose
that the inner one isn't lexically scoped and is some interrupt trying to
run. It may want to do a local return to the GC-RESTART in the interrupt
and when the interrupt has been handled, control may want to pass to the
other GC-RESTART. Maybe a GC-RESTART-BARRIER could accomplish this or maybe
interrupts could do something special or who knows ... 

Here's another -- GC-DEFER ... doing
(GC-DEFER ...code...) says that you want to turn off garbage collection
for the execution of this form. This is for forms that cannot be restarted
if the garbage collector runs. In such a case, the GC-LOSSAGE handler, not
the GC-OVERFLOW handler should be run if a GC feels forced at that time.
Additionally, doing (GC-DEFER ((fixnum 30.) (flonum 50.)) ...) might be
a nicer syntax so that you could say -- "I'm about to do an operation that
will require 30 fixnum cells and 50 flonum cells. If you don't have that 
many, you can do a GC-OVERFLOW type error now but if you enter me you better
not do any GC'ing until I return ..." -- hence interrupts running in that
time that caused GC's would cause GC-LOSSAGE -- if the guy wants to lock out
interrupts too he might want to, but maybe he doesn't want to lock out ^G and
other winners ...

So there's the suggestions for your comments and consideration.
-kmp