From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.9 required=5.0 tests=BAYES_00,FORGED_GMAIL_RCVD, FREEMAIL_FROM autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,86f62fb0f98ad93e X-Google-NewGroupId: yes X-Google-Attributes: gida07f3367d7,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII Path: g2news1.google.com!postnews.google.com!u26g2000yqu.googlegroups.com!not-for-mail From: Warren Newsgroups: comp.lang.ada Subject: Re: Passing Ada Proc as a C Function Pointer Date: Wed, 4 Aug 2010 17:42:16 -0700 (PDT) Organization: http://groups.google.com Message-ID: References: NNTP-Posting-Host: 216.121.235.102 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: posting.google.com 1280968936 11988 127.0.0.1 (5 Aug 2010 00:42:16 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Thu, 5 Aug 2010 00:42:16 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: u26g2000yqu.googlegroups.com; posting-host=216.121.235.102; posting-account=ENgozAkAAACH-stq5yXctoDQeZQP2E6J User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 ( .NET CLR 3.5.30729),gzip(gfe) Xref: g2news1.google.com comp.lang.ada:12867 Date: 2010-08-04T17:42:16-07:00 List-Id: On Aug 4, 2:46=A0pm, Jeffrey Carter wrote: > On 08/04/2010 09:40 AM, Warren wrote: > > and an Ada API function: > > > =A0 =A0 =A0procedure 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 : =A0 =A0out Thread_Context; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Proc =A0 =A0: in =A0 =A0 = Thread_Proc; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Stack =A0 : =A0 =A0out St= ack_Area) > is > =A0 =A0 type C_Context is ...; > =A0 =A0 -- Something C-compatible that corresponds to the C > =A0 =A0 -- definition of avr_thread_context, using only > =A0 =A0 -- convention-C components. > =A0 =A0 pragma Convention (C, C_Context); > > =A0 =A0 procedure Local_Proc is > =A0 =A0 =A0 =A0-- null; > =A0 =A0 begin -- Local_Proc > =A0 =A0 =A0 =A0Proc.all; > =A0 =A0 end Local_Proc; > =A0 =A0 pragma Convention (C, Local_Proc); .. > I presume Thread_Context is not opaque and its contents are accessed on t= he Ada > side. Otherwise you may be able to get away with a convention-C pointer t= o > 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