From: jsidlo@world.std.com (John R Sidlo)
Subject: Re: GC Metering Module
Organization: The World Public Access UNIX, Brookline, MA
Date: Fri, 22 Jan 1993 17:33:33 GMT

I've been following the thread on GC Metering Modules, and have some
observations and comments on the idle loop gc scenarios (I came up with
a similar one), on allocation-area-lists and their interface, and to
persistent storage allocation.

With respect to the idle loop scenarios, Allard writes:
> As you say, the form in the event loop would need some refining to avoid
> calling the garbage collector needlessly, perhaps something like the following.
> Please forgive the Common Lisp usage where I have no Dylan equivalent.  This
> form also assumes there is a way to exit a get-event call at the appropriate
> interval into an idle period.
> 
>   (bind ((ephemeral (first (allocation-areas)))
>          (static (last (allocation-areas)))
>          ((available-bytes integer) (area-available ephemeral)))
>     (when (or (< available-bytes maximum-bytes-needed-per-event)
>               (and (not (id? ephemeral static))
>                    (> (- (get-universal-time) last-event-time)
>                       idle-enough-to-gc-interval)
>                    (< available-bytes (/ (area-size ephemeral) 2))))
>       (garbage-collect ephemeral)))
> 
>  
> 
I note that I've independently come up with a similar scenario with some
different wrinkles, plus some comments.

First, it seems that an interface to a garbage collector could be
machine independent, assuming that the units of measurement are
primitive enough, perhaps in number-of-bits.  David Moon suggested that
a garbage collector he was considering might not work with the
primitives Allard originally defined.  Allards second note, in
particular the quote below about the ordering and catagories of
allocation areas contained in the allocation list, prompted some
thoughts.  One might imagine an <allocation-area-list> class with a
variety of methods that help ensure portability.  These methods might
include those that iterate over the allocation-areas according to some
special ordering or filter, to subset the allocation-areas, to
garbage-collect all appropriate allocation areas.  The aim of these
interfaces would partially be to ensure the possibility of portability.

Second, I agree there could be some additional refinement supporting
when to trigger a garbage collection.  An application event loop is
likely to be in a position to recognize when it seems to be idle. 
Similarly, it should be possible for that event loop to have a decent
idea whether or not real work has been done since the last garbage
collection.  Moreover, if the application could ask the system how busy
it is, something like the following could appear at the end of the event
loop:

(...
  (if (and (i-have-been-idle) 
           (idle-time-garbage-collection-is-ok theSystem))
           (or (i-have-been-busy-since-last-idle-gc)
               (it-appears-there-is-garbage))
      (gc))
  (yield-to-system)
)    
           

Allard's remark:

> Another use that I would make of these tools would be to help manage objects
> that I know will be long-lived.  The following could be an allocation function
> that I would use for such an object.
> 
>   (bind ((original-area (selected-area)))
>     (unwind-protect
>       (begin
>         (select-area (last (allocation-areas)))
>         (make long-lived-jumbo))
>       (select-area original-area)))
> 
and his use of "long-lived" prompted another thought on
allocation-areas.  One could imagine an allocation-area representing a
persistent data store, such as an object-oriented database.  Objects
allocated in such an area would live longer than the running
application, and of course might have different gc strategies.  You can
also imagine an application using several different persistent stores,
so there might be a subset of "persistent-allocation-areas" among all
allocation-areas.  To relate this to a point made above, I might like to
inquire as follows:
(...
  (begin ((all-persistent-stores (choose persistent? theAllocatedAreas))
         ...)
  )  

Of course persistent-allocation areas beg lots of other issues, such as
transactions, querying, and so on, that are too lengthy to go into in a
short note.  But persistent-allocation-areas should be able to behave
like temporal-allocation-areas.  For example:
(define-class <allocation-are>a (<object>) ...)
(define-class <temporal-allocation-area> (<allocation-area>) ...)
(define-class <persistent-allocation-area> (<allocation-area>) ...)
(define-class <allocation-area-list> (<list> ...) ...)

And finally, Allard writes:
> The problem issues I can think of for this approach would be where there are
> different regions for different kinds of objects, instead of different
> lifetimes.  This would shoot the ordering for allocation-areas in the foot, and
> would make area selection be a little weird.  In this case, when an area is
> selected, it could only be used for objects which could be allocated with in.
> 
I'm guessing that some of these problems can be overcome by reordering
or filtering the allocation area lists.

Newsgroups: comp.lang.dylan