comp.lang.ada
 help / color / mirror / Atom feed
From: Warren <ve3wwg@gmail.com>
Subject: Re: Passing Ada Proc as a C Function Pointer
Date: Wed, 4 Aug 2010 17:42:16 -0700 (PDT)
Date: 2010-08-04T17:42:16-07:00	[thread overview]
Message-ID: <cce56782-e45c-4917-819d-30e352659ee6@u26g2000yqu.googlegroups.com> (raw)
In-Reply-To: i3ccj1$2bnh$1@adenine.netfront.net

On Aug 4, 2:46 pm, Jeffrey Carter <spam.jrcarter....@spam.not.acm.org>
wrote:
> On 08/04/2010 09:40 AM, Warren wrote:

> > and an Ada API function:
>
> >      procedure Thread_Start(Context : out Thread_Context; Proc :
> > Thread_Proc; Stack : out Stack_Area) is
...
> > Is it vital that the Thread_Proc procedure also be declared as
>
> > pragma import(C,Proc) ?

Actually, I had meant to say here:

> > pragma EXPORT(C,Proc) ?

> > I'd prefer not to, if possible.

> I'm presuming that you want Ada to call Thread_Start and not need to take
> special steps because Thread_Start calls some C.

Yes, that is correct. This is to become a thick binding in WinAVR to
provide some limited threading capability.

> The 1st step is to translate the C side into something meaningful. "uint8_t*"
> can mean a host of things:

I'm not worried about the data args - for AVR it is sufficient that
I use System.Address.  This is very gnat specific code.

> procedure Thread_Start(Context :    out Thread_Context;
>                         Proc    : in     Thread_Proc;
>                         Stack   :    out Stack_Area)
> is
>     type C_Context is ...;
>     -- Something C-compatible that corresponds to the C
>     -- definition of avr_thread_context, using only
>     -- convention-C components.
>     pragma Convention (C, C_Context);
>
>     procedure Local_Proc is
>        -- null;
>     begin -- Local_Proc
>        Proc.all;
>     end Local_Proc;
>     pragma Convention (C, Local_Proc);
..
> I presume Thread_Context is not opaque and its contents are accessed on the Ada
> side. Otherwise you may be able to get away with a convention-C pointer to
> Thread_Context.

It is opaque, and all I need to pass is a pointer (System.Address is
sufficient for this). I just need to be careful that I allocate
sufficient space to it.

> Are Context and Stack really needed outside Thread_Start?

Oh yes- that's where the thread state and saved registers go,
(in Context) when there is a thread switch etc.  The data area
Stack is the allocated RAM you're going to give as the thread's
stack. So once the thread launches, this area must not move
or get re-used, because the thread will be stomping through it.

The Local_Proc idea is intriguing, but the problem is that the
calling procedure (Thread_Start) may have returned before that
new thread actually gets started.  However, it has suggested
a couple of ideas.

If the Thread_Start were to wait for the new thread to signal
an event, then the Thread_Start could suspend until the new
thread starts. The downside is the added complexity.

OTOH, I could create a Thread_Context that is larger than what
the C routines expect. The Ada side will always be the one
setting aside the Context and Stack space. So I suppose I could
stuff an Ada procedure access (ptr) in it, and have a
C convention proc (in Ada) invoke that, acting as the
trampoline.  It just wastes a little more space but is
simple to do.

I was hoping there was a more elegant gnat solution though.

Warren



  parent reply	other threads:[~2010-08-05  0:42 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-08-04 16:40 Passing Ada Proc as a C Function Pointer Warren
2010-08-04 17:14 ` Dmitry A. Kazakov
2010-08-05  0:24   ` Warren
2010-08-04 18:46 ` Jeffrey Carter
2010-08-04 19:36   ` Dmitry A. Kazakov
2010-08-05  0:42   ` Warren [this message]
2010-08-05  0:55     ` Warren
2010-08-04 19:46 ` Simon Wright
2010-08-05  0:45   ` Warren
2010-08-05  7:33     ` Rolf
2010-08-05 20:50       ` Simon Wright
  -- strict thread matches above, loose matches on Subject: below --
2010-08-05 14:31 Warren
2010-08-05 15:37 ` Warren
2010-08-05 16:51   ` Warren
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox