Raffael Cavallaro <raffaelcavallaro@...> writes:
> What would it take to enable sbcl to lock pointers to foreign (i.e., c
> language) objects (data, pointers, and functions) in memory for future
> reference, and then dispose of it when no longer needed? I know that
Foreign memory isn't touched by GC anyway; it's foreign. Anything you
malloc will stay allocated, at that address, until you free it. If you
need to hold onto it for a particular dynamic extent, you want to wrap
the free in an unwind-protect or something. Once upon a time you
could also have added a finalizer which would free the foreign code
when some Lisp object it was associated with got collected, but
unfortunately finalisation is currently broken.
On x86/gencgc, there's also support for pinning pages in Lisp memory
to protect them from garbage collection: any pointer on the C stack
will cause the page(s) where the object resides to be locked, so as
long as you can keep a pointer on the C stack, it will be safe.
So anything you pass to a foreign call is guaranteed unmovable until
the foreign call returns.
Additionally, on x86 the C stack is also the Lisp control stack, so
calling a Lisp function with the pointer to be protected will cause it
to be pinned until that function returns.
(Hmm. That sounds really rather excessively conservative. I wonder
if I'm talking rubbish)
If you're using PPC that's not relevant to you, because that port
still uses cheneygc, which doesn't have these niceties. It wouldn't
be impossible to port the genreational collector, and I probably will
do if I ever get as far as doing native threads for non-x86 platforms,
but it's not a priority right now. I'm not sure if I'd want to
combine the stacks even if I do: I think that precise scanning of the
control stack is probably desirable where possible.
> one can currently call sb-ext:purify, but doesn't that lock these data
> structures permanently? That wouldn't really work for my purposes - I
> need to be able to purge these foreign structures when they are no
> longer needed or I'll end up with serious memory leaks.
Purify is permanent, yes. But, like GC, it doesn't touch foreign
> A little background - I'm trying to get sbcl to work with Apple's
> Carbon APIs. I'll need to:
Cool. Good luck ...
I don't follow the OpenMCL lists, but I have a feeling this general
topic has come up there in the past. It might be worthwhile checking
with them for previous work in the area.
> 1. pass pointers to large data structures both ways (lisp -> c, c->
> lisp) so that I can manipulate the data in lisp, and display it using
> the platform native c APIs.
If you allocate them in C space, you will _probably_ have to access
them from Lisp using SAPs. If the objects have a roughly
Lisp-compatible layout (e.g. specialised arrays of numbers) there's
some possibility you could allocate them in C space, then slap
a Lisp header on the front. That's a "works in principle but I've
never tried it" strategy; you might have to get quite intimate with
SBCL memory layout if it starts doing odd things.
> 2. provide c language callback routines defined in lisp (using alien
> of course) to native c APIs.
Do the callbacks have a user_data argument or similar? If so, the
simplest way to do this is going to be to write a single Lisp function
that dispatches on the user_data argument, run purify to lock it
into a known address, then write callback functions in C that call
funcall to call into the Lisp dispatch function. Did that make
any sense at all?
If you don't have an argument to the callback function that can be
used to identify why the callback was called, it could all be a lot
http://www.cliki.net/ - Link farm for free CL-on-Unix resources