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]

Re: gh_scm2doubles and friends



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?