[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Chicken-users] define-macro, ffis, and the gc
From: |
felix |
Subject: |
Re: [Chicken-users] define-macro, ffis, and the gc |
Date: |
Wed, 23 Jun 2004 23:42:13 +0200 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040113 |
Eric Merritt wrote:
Guys,
I pretty new to chicken and have a few questions I hope you can help
me with. At the bottom of this message you will find a macro. The most
obvious problem with it is that its way too long. It needs to be
broken up into smaller functional pieces. However, I am not sure how
to do that in chicken, considering that functions defined in the file
are not available at compile time. What is the usual way to handle
this?
You can use `eval-when' to define stuff at compile time:
(eval-when (compile eval) ; <- eval'd in the interpreter as usual, and while
compiling
(define (my-helper ...) ...) )
(define-macro (my-macro ...)
...
(my-helper ...)
...)
My other question
revolves around chicken's gc and malloc/calloc in an ffi. Will the gc
clean up memory allocated in a foreign-lambda or does it need to
explicitly released?
Anything you allocate via [cm]alloc() inside wrapped C code has to be
freed manually. The exception is the `c-string*' result type, which
accepts a malloc'd char * and frees it after copying it into Scheme space.
If the gc handles the clean up, how do you handle
issues where special actions need to be taken to free the memory?
You can use finalizers (`set-finalizer!') to attach a procedure to
a datum, that will be called once the object is not used anymore.
To use this facility with malloc'd C data, you can wrap the data
into a record, like this:
% cat x.scm
(define-record wrapper ptr)
(define-foreign-type wrapper-type c-pointer wrapper-ptr make-wrapper)
(define alloc
(foreign-lambda* wrapper-type () "return(malloc(42));") )
(define free
(foreign-lambda void "free" wrapper-type) )
(set-gc-report! #t) ; to see some finalizer output
(define x (alloc))
(set-finalizer! x (lambda (x) (print "finalizin'") (free x)))
(print x)
(print (wrapper-ptr x))
(set! x #f) ; now remove global reference to it
(gc #t) ; force all pending finalizers to be run
(print "end.")
% csc x.scm
% x
#<wrapper>
#<pointer 8052640>
GC: 1 item(s) in finalizer table
GC: finalizer table: size=64, max=-1
GC: pending finalizers: 1
GC: queueing 1 finalizers
GC: level 1 gcs(minor) 6 gcs(major) 1
GC: stack bffef7f0 bfffbf60 bffff7f0
GC: from 404d6008 404ea4fc 40513098 144f4
GC: to 40498008 40498008 404d5098
finalizin'
GC: level 1 gcs(minor) 0 gcs(major) 2
GC: stack bffef7f0 bfffe540 bffff7f0
GC: from 40498008 404ac4e0 404d5098 144d8
GC: to 404d6008 404d6008 40513098
end.
GC: level 1 gcs(minor) 0 gcs(major) 3
GC: stack bffef7f0 bfffe610 bffff7f0
GC: from 404d6008 404ea4e0 40513098 144d8
GC: to 40498008 40498008 404d5098
%
cheers,
felix