[gambit-list] Anyone else working in a schemey wrapper for c structs/unions/types?
Mikael
mikael.rcv at gmail.com
Wed Dec 25 19:21:58 EST 2013
https://github.com/feeley/gambit/pull/61 - for a quick proof of concept,
that's a very neat use of the ffi type!!!
2013/12/25 Estevo <euccastro at gmail.com>
>
> I have never been aware of anything like that. Can you provide a proof
>> of concept example code that shows how weak references to a FFI object
>> would be inconsistent?
>>
>
> The problem is not that they're inconsistent. The problem is they can't
> really tell you when an object that is depended upon is safe to free. I
> gave an example of that in this thread:
>
>
> https://mercure.iro.umontreal.ca/pipermail/gambit-list/2013-December/007335.html
>
So you tried to somehow use wills to force GC order? Without having studied
this, I guess that was not what they were intended for in the first place
and it makes good sense that that did not work out well.
>> You can implement this kind of behavior in Gambit (i.e. B is referenced
>> to by or actually contained in A so you want freeing of B to be conditioned
>> to the freeing of A happening before) yourself, for instance by
>>
>> 1) ensuring you have a reference to B in some vector or alike, one that
>> guaranteedly will stick around until A is freed. Also, you could
>>
>
> Once user code gets hold of A, pure Scheme code can't really know when
> it's OK to let go of that vector. It's the same problem. Of course you
> can keep a reference forever, but you don't want to hold on to unneeded
> memory either.
>
You should be able to work that out and question is just how heavy it would
be implementation-wise to do, no??
If not why not?
> 2) use the "refcount" facility that Gambit exports to the C world, to
>> keep B's refcount +1 as long as A refers to it, and then have A's release
>> procedure -1 its refcount on invocation.
>>
>
> Something like this might work, thanks! I had given up on foreign release
> functions because they are C functions that can only be set (or so I
> thought) per foreign object type (the ones you create in c-define-type) and
> not per instance, they can't be closures, and they won't get any arguments
> but the foreign's pointer to C data. Also, you can only set one, so if you
> use it for this you can't use it for anything else.
>
> But these restrictions need not be showstoppers. A scheme that might work:
> - on initalization, create an ___alloc_rc'ed table[1] and assign a global
> C pointer to it
> - whenever you create a dependent foreign pointer F, store in the table a
> reference to its dependent object D, keyed by the address of the F's C
> pointer, and
> - set a release function for F that will clear that entry in the table.
>
Why do you need a "table" (by table here you mean resizable vector)?
> This should work because unlike wills, release functions will only be
> called when their object is not reachable from Scheme code (barring FFI
> black magic).
>
> What practical task are you solving?
>>
>
> I'm making a library that lets you define C struct/union/type
> constructors, accessors and mutators using a syntax analogous to that of
> define-structure.
>
Nice!
Gambit's builtin functionality for this is fully sufficient at Gambit's
level of abstraction over the underlying system, and indeed there's plenty
of space for higher-level abstractions that more in this area.
So the totality of what you are looking to provide is
a) the c-struct form which is analogous to define-type with
b) Scheme-like automatic dependency GC-reference handling between c
structure instances as discussed here
?
> Here's how you define C structure wrappers:
>
> https://github.com/euccastro/gambit-SDL2/blob/master/c-test-ffi.scm
>
> and here's how you use them
>
> https://github.com/euccastro/gambit-SDL2/blob/master/test-ffi.scm
>
> Here's a non-test example:
>
> https://github.com/euccastro/gambit-SDL2/blob/master/sdl.scm
>
> This is from a very old version and it shows that I didn't know what I was
> doing :), but it does showcase the user interface. The point is that using
> C structures from Gambit code should be effortless, straightforward, safe,
> and fit well both with Scheme and with FFI code that doesn't follow your
> approach.
>
> I'll give the scheme above a go and let you know how it goes. I think the
> solution involving my patch[2] should yield better performance because it
> doesn't involve any table following and,
>
> not requiring the use of release functions,
>
well, if it's some exotic type where you need C code invoked for the
release work then indeed there is the need for a release function, however
if that's not the case then yep right, with this model you suggest, there's
no need for a release function.
> allows you to set the last parameter of c-define-type to false. But maybe
> this won't matter in practice.
>
> Thanks again!
>
> [1] Globals won't do because the garbage collector doesn't scan those.
> Movable objects won't do because you can't reliably keep a C pointer to
> them.
> [2] Which, by the way, I've simplified down to a 5-line change. See
> https://github.com/feeley/gambit/pull/61
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20131226/3c4f3a26/attachment.htm>
More information about the Gambit-list
mailing list