chicken-users
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]