l4-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: IDL issue - struct return vs. cap return


From: Jonathan S. Shapiro
Subject: Re: IDL issue - struct return vs. cap return
Date: Mon, 09 Jul 2007 15:14:25 -0400

On Mon, 2007-07-09 at 18:10 +0200, Neal H. Walfield wrote:
> At Sun, 08 Jul 2007 00:03:10 -0400,
> Jonathan S. Shapiro wrote:
> 
> > If we choose to adopt the "return the return value" convention, it is
> > still necessary to handle capability returns specially in C, because the
> > caller must say where the incoming capability is to be stored (we cannot
> > get compiler help for this from an unmodified compiler).
> 
> How is this different from returning a struct?  There is a general
> rule of thumb not to return large structs from function calls.
> Instead, the convention is for either the function allocates memory or
> the caller to pass a pointer to a block of allocated memory.

The convention you describe is actually unnecessary, because good
compilers already implement it automatically. If you write something of
the form:

   s = f(...);

where s is some structure type larger than (typically) 2 words, most
calling conventions will automatically rewrite it as:

   f(..., &s);

Many, but not all compilers, will automatically suppress this rewrite
for small, registerizable structs. The convention you describe is mainly
relevant for legacy compilers these days.


But to answer your question:

The difference is that in the structure case all of the storage being
allocated is known to the compiler. if you have some large structure
type S, you can write:

   S s;
   f(&s);

In contrast, if you write:

  cap_t cap;
  g(&cap);

you have written complete garbage. A cap_t is effectively a *pointer*
type. What you wanted to write was something like:

  cap_t cap = alloc_cap_location();
  g(cap);

That is: cap_t is an (opaque) capability *reference*, it is not a
capability.


Because cap_t is a reference, you basically have two options if you want
to return a cap_t from an IDL procedure:

  1. Use a well-known return location, e.g. capability register 2.
  2. Call the capability location allocator from inside the stub, as
     in:

     f() {
      cap_t _retVal = alloc_cap_location();
      DO_SYSCALL_HERE(_retVal);
      return _retVal;
    }

The problem with this is that the IDL runtime system just got in bed
with the capability storage allocator, and we are left needing to solve
the problem of how to *deallocate* capability locations when they are no
longer in use.

I can think of a wide range of conservative collection techniques that
would be very effective here, but that adds yet *more* complexity to the
IDL subsystem...

shap
-- 
Jonathan S. Shapiro, Ph.D.
Managing Director
The EROS Group, LLC





reply via email to

[Prev in Thread] Current Thread [Next in Thread]