Hi,
I am wrapping a void * cffi pointer and some extra information in a
CLOS object. When the object is garbage-collected, I would like to
have the memory location freed. I have found out how to do
finalization in SBCL, but I want to make my code portable.
I have seen finalize implementations with #+ directives floating
around, could somebody post a reasonably comprehensive version? Or is
there a library to do this?
Thanks,
Tamas
On Tue, 03 Jul 2007 11:23:48 +0200, Tamas Papp <······@gmail.com> wrote:
> I have seen finalize implementations with #+ directives floating
> around, could somebody post a reasonably comprehensive version?
You can look at the source of RDNZL which includes finalizing code for
LispWorks, AllegroCL, SBCL, CLISP, and Corman Lisp. (CMUCL is
probably similar to SBCL.) Or you can wait for someone to do the work
for you.
Edi.
--
Lisp is not dead, it just smells funny.
Real email: (replace (subseq ·········@agharta.de" 5) "edi")
Tamas Papp <······@gmail.com> writes:
> I am wrapping a void * cffi pointer and some extra information in a
> CLOS object. When the object is garbage-collected, I would like to
> have the memory location freed. I have found out how to do
> finalization in SBCL, but I want to make my code portable.
>
> I have seen finalize implementations with #+ directives floating
> around, could somebody post a reasonably comprehensive version? Or is
> there a library to do this?
there is a small library out there called trivial-garbage with
finalization code for several CL implementations.
Regards,
Marco
Marco Gidde wrote:
> Tamas Papp <······@gmail.com> writes:
>
>> I am wrapping a void * cffi pointer and some extra information in a
>> CLOS object. When the object is garbage-collected, I would like to
>> have the memory location freed. I have found out how to do
>> finalization in SBCL, but I want to make my code portable.
A related question -- are finalizers called when the object falls out of
scope, or when a GC is called?
If the latter, how can we instruct the GC to be aware of limited
resources (like malloc'd memory, file handles, etc.)?
mfh
On Jul 3, 2:19 pm, Mark Hoemmen <············@gmail.com> wrote:
> Marco Gidde wrote:
> > Tamas Papp <······@gmail.com> writes:
>
> >> I am wrapping a void * cffi pointer and some extra information in a
> >> CLOS object. When the object is garbage-collected, I would like to
> >> have the memory location freed. I have found out how to do
> >> finalization in SBCL, but I want to make my code portable.
>
> A related question -- are finalizers called when the object falls out of
> scope, or when a GC is called?
Maybe when the GC is called. There are no general guarantees when or
if a finalizer will be called. That's basically why they're not in
the standard.
> If the latter, how can we instruct the GC to be aware of limited
> resources (like malloc'd memory, file handles, etc.)?
Finalization is the wrong tool for this. Look in the Lisp concept of
"resources".
···@itasoftware.com wrote:
>> If the latter, how can we instruct the GC to be aware of limited
>> resources (like malloc'd memory, file handles, etc.)?
>
> Finalization is the wrong tool for this. Look in the Lisp concept of
> "resources".
Would you happen to have some suggested reading for this? Googling
"Lisp resources" brings up general reading on Lisp, and the usual
documentation isn't helpful.
Many thanks,
mfh
On Jul 3, 2:57 pm, Mark Hoemmen <············@gmail.com> wrote:
> ····@itasoftware.com wrote:
> >> If the latter, how can we instruct the GC to be aware of limited
> >> resources (like malloc'd memory, file handles, etc.)?
>
> > Finalization is the wrong tool for this. Look in the Lisp concept of
> > "resources".
>
> Would you happen to have some suggested reading for this? Googling
> "Lisp resources" brings up general reading on Lisp, and the usual
> documentation isn't helpful.
Not offhand, it's an old concept. The pdf Alexey Goldin recommends
calls them storages and gives and example with-storage macro
definition. Basically resources are the Lispy way of explicitly
managing object allocation and deallocation. Objects are created on a
list, typically held in a defvar, and functions are implemented to
allocate and deallocate objects explicitly. It is perfectly
reasonable for deallocation to simply clean up the object and put it
back on a free list if object construction is expensive (e.g. I did
that for processes once while working on a parallel Common Lisp
project).
Generally a wrapper macro named WITH-foo is implemented that executes
a block of code with an object allocated for it. This works out to be
much like C++ stack allocation with constructors and destructors but
IMHO much clearer.
On Jul 3, 12:44 pm, ····@itasoftware.com wrote:
> Generally a wrapper macro named WITH-foo is implemented that executes
> a block of code with an object allocated for it. This works out to be
> much like C++ stack allocation with constructors and destructors but
> IMHO much clearer.
*nods* yes, that's probably the best choice in terms of the
performance / ease-of-use tradeoff...
Many thanks!
mfh
On 2007-07-03 20:57:55 +0200, Mark Hoemmen <············@gmail.com> said:
> ···@itasoftware.com wrote:
>>> If the latter, how can we instruct the GC to be aware of limited
>>> resources (like malloc'd memory, file handles, etc.)?
>>
>> Finalization is the wrong tool for this. Look in the Lisp concept of
>> "resources".
>
> Would you happen to have some suggested reading for this? Googling
> "Lisp resources" brings up general reading on Lisp, and the usual
> documentation isn't helpful.
>
> Many thanks,
> mfh
Lisp Machine Manual, 6th Edition
Chapter 6. Resources
http://common-lisp.net/project/bknr/static/lmman/resour.xml
(you need something like Firefox/Camino to view the contents)
--
http://lispm.dyndns.org/
On Jul 3, 11:19 am, Mark Hoemmen <············@gmail.com> wrote:
>
> A related question -- are finalizers called when the object falls out of
> scope, or when a GC is called?
>
When the GC is called.
- Luke
Marco Gidde <···········@tiscali.de> writes:
> Tamas Papp <······@gmail.com> writes:
>
>> I am wrapping a void * cffi pointer and some extra information in a
>> CLOS object. When the object is garbage-collected, I would like to
>> have the memory location freed. I have found out how to do
>> finalization in SBCL, but I want to make my code portable.
>>
>> I have seen finalize implementations with #+ directives floating
>> around, could somebody post a reasonably comprehensive version? Or is
>> there a library to do this?
>
> there is a small library out there called trivial-garbage with
> finalization code for several CL implementations.
Thanks Marco,
I also found that there is a cffi:finalize that does the thing I want.
Since this thread has drifted towards resources, I have a conceptual
question. Suppose I have a resource (eg a Cairo context in
cl-cairo2), is a pointer to a C structure.
(defclass foo () ((pointer :initform nil)))
The user has to be able to close the resource explicitly (eg in
cl-cairo2, this indicates that he has finished drawing and the file
can be closed), so there is a destroy method:
(defmethod destroy ((object foo))
(with-slots (pointer) object
(when pointer
(call_c_api_to_destroy pointer)
(setf pointer nil))))
But suppose that I also want to register a finalizer, and have the
object destroyed when it is garbage collected. The documentation of
cffi:finalize says
For portability reasons, function should not attempt to look at
object by closing over it because, in some lisps, object will
already have been garbage-collected and is therefore not accessible
when function is invoked.
So how is the finalizer supposed to look at pointer to determine if
the resource has already been freed explicitly with destroy?
Thanks,
Tamas
Tamas Papp <······@gmail.com> writes:
[...]
>
> Since this thread has drifted towards resources, I have a conceptual
> question. Suppose I have a resource (eg a Cairo context in
> cl-cairo2), is a pointer to a C structure.
>
> (defclass foo () ((pointer :initform nil)))
>
> The user has to be able to close the resource explicitly (eg in
> cl-cairo2, this indicates that he has finished drawing and the file
> can be closed), so there is a destroy method:
>
> (defmethod destroy ((object foo))
> (with-slots (pointer) object
> (when pointer
> (call_c_api_to_destroy pointer)
> (setf pointer nil))))
>
> But suppose that I also want to register a finalizer, and have the
> object destroyed when it is garbage collected. The documentation of
> cffi:finalize says
>
> For portability reasons, function should not attempt to look at
> object by closing over it because, in some lisps, object will
> already have been garbage-collected and is therefore not accessible
> when function is invoked.
>
> So how is the finalizer supposed to look at pointer to determine if
> the resource has already been freed explicitly with destroy?
It's not supposed to:
(defmethod destroy ((object foo))
(with-slots (pointer) object
(when pointer
(call_c_api_to_destroy pointer)
(setf pointer nil)))
(cancel-finalization object))
Rudi
Rudi Schlatte <····@constantly.at> writes:
> Tamas Papp <······@gmail.com> writes:
>
> [...]
>>
>> Since this thread has drifted towards resources, I have a conceptual
>> question. Suppose I have a resource (eg a Cairo context in
>> cl-cairo2), is a pointer to a C structure.
>>
>> (defclass foo () ((pointer :initform nil)))
>>
>> The user has to be able to close the resource explicitly (eg in
>> cl-cairo2, this indicates that he has finished drawing and the file
>> can be closed), so there is a destroy method:
>>
>> (defmethod destroy ((object foo))
>> (with-slots (pointer) object
>> (when pointer
>> (call_c_api_to_destroy pointer)
>> (setf pointer nil))))
>>
>> But suppose that I also want to register a finalizer, and have the
>> object destroyed when it is garbage collected. The documentation of
>> cffi:finalize says
>>
>> For portability reasons, function should not attempt to look at
>> object by closing over it because, in some lisps, object will
>> already have been garbage-collected and is therefore not accessible
>> when function is invoked.
>>
>> So how is the finalizer supposed to look at pointer to determine if
>> the resource has already been freed explicitly with destroy?
>
> It's not supposed to:
>
> (defmethod destroy ((object foo))
> (with-slots (pointer) object
> (when pointer
> (call_c_api_to_destroy pointer)
> (setf pointer nil)))
> (cancel-finalization object))
Thanks Rudi,
This was enlightening.
Tamas
Tamas Papp <······@gmail.com> writes:
> I also found that there is a cffi:finalize that does the thing I want.
This was the first portable FINALIZE that I used but AFAIK it is
deprecated in favour of trivial-garbage :-)
Regards,
Marco
On Jul 4, 1:40 am, Tamas Papp <······@gmail.com> wrote:
> (defmethod destroy ((object foo))
> (with-slots (pointer) object
> (when pointer
> (call_c_api_to_destroy pointer)
> (setf pointer nil))))
You might want to setf pointer to a null pointer instead of to NIL, so
that the type of pointer is always a C pointer. Not a big deal but it
could be a useful invariant.
mfh
Mark H. <············@gmail.com> wrote:
+---------------
| On Jul 4, 1:40 am, Tamas Papp <······@gmail.com> wrote:
| > (defmethod destroy ((object foo))
| > (with-slots (pointer) object
| > (when pointer
| > (call_c_api_to_destroy pointer)
| > (setf pointer nil))))
|
| You might want to setf pointer to a null pointer instead of to NIL, so
| that the type of pointer is always a C pointer. Not a big deal but it
| could be a useful invariant.
+---------------
Good point. In CMUCL, for example, NIL is certainly not a null pointer!
Nor is it a "C pointer" in the usual sense. [It has low-tag bits set.]
-Rob
-----
Rob Warnock <····@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607
On Jul 3, 4:23 am, Tamas Papp <······@gmail.com> wrote:
> Hi,
>
> I am wrapping a void * cffi pointer and some extra information in a
> CLOS object. When the object is garbage-collected, I would like to
> have the memory location freed. I have found out how to do
> finalization in SBCL, but I want to make my code portable.
>
> I have seen finalize implementations with #+ directives floating
> around, could somebody post a reasonably comprehensive version? Or is
> there a library to do this?
>
> Thanks,
>
> Tamas
You might want to look through this IMHO very useful paper:
http://p-cos.net/lisp-ecoop06/pdf/112999.pdf
On Jul 3, 12:14 pm, ··············@gmail.com"
<·············@gmail.com> wrote:
> You might want to look through this IMHO very useful paper:
>
> http://p-cos.net/lisp-ecoop06/pdf/112999.pdf
Cool, many thanks!
I guess you could also "roll your own" resource management system
(e.g., for file handles), using reference counting and a separate
resource manager thread. Every so often the thread runs, and disposes
of objects with a zero reference count. Problem is, every time you
allocate a resource, you have to do thread synchronization of some
sort, but for the case "small number of scarce resources" it should be
OK.
mfh