[PPL-devel] pointer "ownership" in the C API?

Roberto Bagnara bagnara at cs.unipr.it
Thu Mar 26 19:39:39 CET 2009


Basile Starynkevitch wrote:
 > A newbie question regarding the C API. What is the pointer ownership
 > convention, and where could I find tiny examples or tests of the C API of
 > PPL?

The C language interface of the PPL is meant to replicate, as closely as
possible, what is available in the C++ language interface.

Usually, the C++ interface provides for each of its datatype:

  - (copy) constructors  ==> (in C)  ppl_new_*
  - copy assignment      ==> (in C)  ppl_assign_*
  - destructor           ==> (in C)  ppl_delete_*

with the semantics usually adopted when defining so-call "concrete types"
having value (not reference) semantics.
Unless otherwise stated, copy construction and assignment are implemented as
_deep_ copy operations and provide no reference counting.
(NOTE: a form of reference counting is implemented for the elements of
powerset objects.)

Regarding ownership:

1) After a call to a ppl_new_<TYPE>* method, the caller has to take
    responsibility of the newly created object (usually, the first argument
    of the call, explicitly passed as a pointer, i.e., ppl_<TYPE>_t*).
    That is, the rule of thumb is that you get ownership if there is the
    "new" in the function name. As an example of a resource that you do *not*
    own is the resource pointed by pcs after a call to function:

   int ppl_Polyhedron_get_minimized_constraints
      (ppl_const_Polyhedron_t ph,
       ppl_const_Constraint_System_t* pcs);

2) The one and only way to release a resource r *that you are owning*
     is by calling ppl_delete_<TYPE>(r).

3) Except for case 2) above, ownership is preserved for all input arguments
    passed as ppl_<TYPE>_t or ppl_const<TYPE>_t.
    No matter if these arguments are modified or not during the call, the
    responsibility for their resources does not change (i.e., typically the
    caller will be responsible for calling ppl_delete at some time).


Some of the constructors for PPL objects avoid the need of deep copies.
For instance, we have

   int ppl_new_C_Polyhedron_recycle_Constraint_System
   (ppl_Polyhedron_t* pph, ppl_Constraint_System_t cs);

This will build a new polyhedron *reusing* the data structures provided
in the input argument cs, thereby avoiding the expensive copy.

BEWARE: after calling the function above, the input argument cs is still
a well behaved Constraint_System object owned by the caller: you simply
cannot predict its contents, which might have changed. That is, the caller
is still responsible of properly destroy cs if it is no longer needed, by
calling

    ppl_delete_Constraint_System(cs);

 > So, I made a ppl_Coefficient_t (let's call it k) using ppl_new_Coefficient_from_mpz_t. [BTW,
 > perhaps a ppl_new_Coefficient_from_long_long or a
 > ppl_new_Coefficient_from_int32 might be useful]
 >
 > Then I am filling a ppl_Linear_Expression_t (let's call it l) using ppl_Linear_Expression_add_to_coefficient with the same coeffiient k.
 >
 > Should I explicitly delete by calling ppl_delete_Coefficient(k), or is k now "owned" by l and not available anymore?

As said above, a _copy_ of k has gone into l.
k is still owned by you: you can reuse it, assign to it, etc.
and finally you have to call ppl_delete_Coefficient(k).

 > Could I use twice the same k in different calls to ppl_Linear_Expression_add_to_coefficient?

Yes.

 > I would suppose that PPL use a refcounting scheme as its memory management
 > (or garbage collection) scheme. Is it correct? Who/when are the refcounters
 > incremented & decremented? Is there a C API to e.g. force incrementation of
 > the refcounter (like GTK has)?

No, usually there is no reference counting scheme.
As said above, we have a reference counting in our Powerset datatypes, but
this is transparent to the users of all the language interfaces.

More generally, you can regard the C interface as providing the basic services
around which the client application can build its own abstractions.  Reference
counting schemes are one such possibility.

 > BTW, a more general question is about the philosophy of memory management in
 > PPL, especially when interfacing PPL to some language. Since my GCC MELT can
 > be percieved as some language (the MELT lisp dialect) with its runtime (the
 > MELT garbage collector, above the GGC inside GCC), I could view the
 > interfacing of PPL inside MELT as a language binding of
 > PPL.

Not sure we understand the question.  The basic design principles of the
PPL interfaces are:

1) try to provide interfaces that are "natural" in the  interfaced language;
2) do the basic things efficiently and do not interfere with further
    abstractions user may want to implement.

 > In particular, detailed explanation of Ocaml binding to PPL is welcome,
 > since I happen to know quite well Ocaml (and the C coding rules required by
 > its runtime).

We suggest you look into the library's manuals first (core, C interface
and OCaml interface).  If something is missing there, please let us know.

For the C interfaces, and additional source of examples is the
ppl_lpsol program in demos/ppl_lpsol.
Cheers,

    Enea and Roberto

-- 
Prof. Roberto Bagnara
Computer Science Group
Department of Mathematics, University of Parma, Italy
http://www.cs.unipr.it/~bagnara/
mailto:bagnara at cs.unipr.it



More information about the PPL-devel mailing list