Changeset 5796 in project


Ignore:
Timestamp:
08/28/07 23:56:43 (12 years ago)
Author:
wmfarr
Message:

Changes applied for wmfarr (18.95.7.238) through svnwiki:

Fixed typos, added "Why would you want to do this" section.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • wiki/allocating-c-structures-under-control-of-the-chicken-gc

    r5795 r5796  
    11== Allocating C Structures Under the Control of the Chicken GC
    22
    3 Chicken has an unusual garbage collection, roughly following the procedure described in [[http://home.pipeline.com/~hbaker1/CheneyMTA.html|Cheney on the MTA, Part II]].  Please keep in mind the manual sections [[Data representation]] and [[Interface to external functions and variables]] while you read this section.
     3[[toc:]]
     4
     5This tip describes how to allocate C structures such that they will be under the control of the Chicken garbage collector.
     6
     7Chicken has an unusual garbage collection scheme, roughly following the procedure described in [[http://home.pipeline.com/~hbaker1/CheneyMTA.html|Cheney on the MTA, Part II]].  Please keep in mind the manual sections [[Data representation]] and [[Interface to external functions and variables]] while you read this.
    48
    59The code in this section will be a mix of C and Scheme; recall that you can embed C code directly in your Scheme programs using {{(foreign-declare CODE-STRING)}}.
     
    3842</enscript>
    3943
    40 to represent this object within Chicken.  Unfortunately, if we do that, the procedures {{body-m}}, {{body-q}}, etc, will expect to have foreign pointer objects which contain a pointer to a {{body}} object.  But, this body object must be allocated outside the GC-managed heap, because the pointer in a foreign-pointer is not scanned during garbage collection.  To automatically manage such storage, we must use {{set-finalizer!}} (see [[Unit library]]), and if we want to create 1M bodies, we'll need 1M finalizers, which won't make Chicken very happy.
     44to represent this object within Chicken.  Unfortunately, if we do that, the procedures {{body-m}}, {{body-q}}, etc, will expect to have foreign pointer objects which contain a pointer to a {{body}} object.  But, this body object must be allocated outside the GC-managed heap, because the pointer in a foreign-pointer is not scanned during garbage collection.  To manage it, we must either set a finalizer for the pointer object which contains it (using {{set-finalizer!}}) or deallocate it by hand.  Neither of these is an attractive option for lots of data (maybe we're running a [[http://www.mpa-garching.mpg.de/galform/millennium/|Big Simulation]]).
    4145
    4246So, we'll have to do things by hand.  First, let's define the body tag.  Since bodies will be fixed-size bytevectors, we'll use
     
    4852This stores the size of the data in a body struct (minus the tag size), sets the bit which tells the GC that we're dealing with a bytevector, and gives a body the (arbitrary) scheme type {{string}}. 
    4953
    50 Now we define a make-body Scheme procedure, which takes a mass, f64vector position, and f64vector momentum and produces a body:
     54Now we define a {{make-body}} Scheme procedure, which takes a mass, f64vector position, and f64vector momentum and produces a body:
    5155
    5256<enscript highlight=scheme>
     
    118122
    119123You can't.  Sorry.  Break your data up into one atomic struct which stores all the non-pointers, and then a "pointer" struct which stores a pointer to the atomic data, and all other pointers involved in your datastructure.
     124
     125=== Allocating large data
     126
     127This is also not a good idea---it's easy to overflow the stack (which is the nursery in the generational GC that Chicken uses).  It's non-trivial to allocate some data directly in the second generation.  If you absolutely must do this, then have a look at {{C_allocate_vector}} in the {{runtime.c}} file of the Chicken distribution.  Good luck.
     128
     129=== Why Would You Want to do This?
     130
     131==== Speed
     132
     133Chicken's allocation is '''fast'''.  Much faster than {{malloc}} and {{free}}---it just requires bumping the stack pointer.  So, if you're looking for speed (which you probably are if you're writing C code for Chicken) you're much better off using it than trying to {{malloc}} your datastructures and stuff them into Chicken's {{pointer}} type.
     134
     135==== Convenience
     136
     137If you {{malloc}} your datastructures, you'll have to either
     138
     139* Explicitly {{free}} them when you're done OR
     140* Register a finalizer for them using {{set-finalizer!}}
     141
     142The first option is not attractive if you have complicated data with lots of pointers between structures (that's why GC's were invented, after all).  The second option is OK for a couple of objects, but Chicken doesn't play very well with millions of finalizers registered.  If you want to allocate a lot of objects, don't register finalizers for them.
Note: See TracChangeset for help on using the changeset viewer.