This is the mail archive of the guile@cygnus.com mailing list for the guile project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Isn't the numeric group also talking about these issues?
When converting a Scheme vector to a C vector of doubles, it's
important in some applications to not to copy any more than necessary.
When operating on uniform vectors of doubles, no copying is needed at
all; C code should be able to get a reference to the body of the
vector. That reference needs to be traced somehow, so that Guile's GC
knows not to free the vector.
One approach would be for Guile to hand out a "lease" to a vector's
contents. Something like this:
double *gh_lease_doubles (SCM VECTOR, gh_lease *LEASE);
Convert the Scheme vector VECTOR to a C array of doubles, and
return a pointer to that array. The returned array may or may not
share memory with VECTOR. Modifications to the returned array
within the proper range of indices will have undefined (but safe)
effects on the contents of VECTOR.
This function sets *LEASE to a `lease' for the returned array.
The caller is responsible for passing *LEASE to `gh_free_lease'
when it is done using the returned array. If the returned array
shares memory with VECTOR, then VECTOR will not be garbage
collected until this call; if the returned array is a copy, then
this call will free its storage.
SCM gh_unlease_doubles (gh_lease LEASE)
Convert the array returned by the function which returned LEASE
into a Scheme vector of the appropriate type. The returned object
may or may not be identical to the one passed to the original
function.
void gh_free_lease (gh_lease LEASE)
Free a lease on a possibly copied object. LEASE must be a lease
object returned by some `gh_lease_' function, which returned
either a copy of or a reference to a Scheme object. If it
returned a copy, this function will free it. If it returned a
reference, the Scheme object is protected from garbage collection
until this function is called.
void gh_lease_shared (gh_lease LEASE)
Return true iff the function that returned LEASE shared space with
the original Scheme object.
We could use a similar strategy to handle string contents. However, I
think gh should still provide straightforward copying functions, for
code that doesn't want to deal with the complexity, and can afford a
copy.
I think the typechecking is cleaner if leases are a separate object
from the returned array, but if you don't mind casting pointers to
integral types, then we could use the array itself as the lease
identifier, and store it in a hash table. Then you wouldn't have
lease objects flying around.
The example code becomes:
SCM
example (SCM myvect)
{
gh_lease lease;
double *mem;
mem = gh_lease_doubles (myvect, &lease);
some_function (mem, gh_length (myvect));
return gh_unlease_doubles (lease);
}
This will copy myvect only when sharing is not possible (i.e., it's
actually a non-uniform vector, or a vector of integers, etc.).
Does this sound appropriate?