comp.lang.ada
 help / color / mirror / Atom feed
From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: Interrupts handling in ADA
Date: Tue, 13 Dec 2011 16:39:45 +0100
Date: 2011-12-13T16:39:45+01:00	[thread overview]
Message-ID: <wtlfx7fgfblu$.6l7fnsx25iyo.dlg@40tude.net> (raw)
In-Reply-To: 7a17c1d0-30dd-47b8-a800-3575a8793fbe@d10g2000vbf.googlegroups.com

On Tue, 13 Dec 2011 06:51:25 -0800 (PST), Ada BRL wrote:

> On 13 Dic, 14:04, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:
>> On Tue, 13 Dec 2011 05:11:14 -0800 (PST), Ada BRL wrote:
>>> On 11 Dic, 09:23, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
>>> wrote:
>>>> On Sat, 10 Dec 2011 12:43:58 -0800 (PST), Ada @ BRL wrote:
>>>>> The environment of ADA applcation is:
>>>>> I have 4 tasks that execute at the same time:
>>>>> one is the main task,
>>>>> the other three execute a "read" from network (socket) function inside
>>>>> their bodies (on the other side there's the C/C++ application with 3
>>>>> network sockets).
>>>>> [I decided to use the sockets instead of dll/lib import because this approach hasn't worked... =( ]
>>
>>>> What dll import has to do with sockets, except that sockets usually are
>>>> provided by a library?
>>
>>> I would have liked to use dll import to exchange data between C stuff
>>> and Ada program instead of using two programs (C and Ada)
>>> communicating through sockets...
>>
>> You can link to an import library from Ada without any problems. Which OS
>> are you using?
> 
> Windows 7 64 bit, Home Premium SP1 ...
> I have tried in many ways to import symbols but it was impossible...
> I had a linker error: couldn't find exported symbols...
> I've copied the dll into all the possible folder of my project.

No, you link to the import library, that is *.lib, not *.dll. It is also
possible to load dynamically using LoadLibrary etc. Both works perfectly
well and simple with GNAT.

The simplest way is to create a gpr-file for the external library and
include it into your Ada project using "with." GNAT knows what to do next.

>> No, OS event objects and entry calls assume that the recipient is inactive
>> and thus is ready to accept the notification. That is a non-preemptive
>> model.
> 
> Does this means that the main task has to be in wait for event state
> (blocked and so NOT running)?

Yes, if the main task is the subscriber.

If you look at how GUI's are built, they do exactly this: run the
messages/events/signal processing loop, which does nothing when there is no
messages/events/signals.

>> Software interrupts are preemptive. An interrupt breaks the execution of
>> the recipient. Like with exceptions there are two models of what happens
>> after interrupt has been serviced: continuation back from the point where
>> the task was interrupted vs. winding up the stack and aborting some stuff
>> with continuation from a definite point. AST's are usually like former,
>> Ada's ATC are like latter.
> 
> Sorry what does ATC stand for?

Asynchronous Transfer of Control.

>> the task was interrupted vs. winding up the stack and aborting some stuff
>> with continuation from a definite point. AST's are usually like former,
>> Ada's ATC are like latter.
> 
> I haven't understood well...
> 
> With entry / accept will I use AST or ATC?

ATC in Ada is like this (example from the language manual):

    select
        Terminal.Wait_For_Interrupt;
        Put_Line("Interrupted");
    then abort
        -- This will be abandoned upon terminal interrupt
        Put_Line("-> ");
        Get_Line(Command, Last);
        Process_Command (Command (1..Last));
    end select;

You have some piece of code executing (between abort and end select) while
waiting for some event (the entry call right after select). When event
happens, the code is aborted and you go to the part
Put_Line("Interrupted");

BUT: Just don't worry about ATC, it is not a good idea to use it, almost
always.

> if I have this piece of code inside main task body:
> 
> do stuff before;
> accept event;
> do stuff after;

A more complete picture is:

   do stuff before;
   accept event do
      do stuff upon rendezvous;
   end;
   do stuff after;

> The main thread is blocked onto "event" barrier, when socket calls
> Main.event it can continue and perform "do stuff after".
> 
> Code of socket body:
> 
> do stuff before;
> Main.event;
> do stuff after;
> 
> Does the socket continue its execution after calling to Main.event, in
> parallel with main task or will it be blocked until the main task
> blocks itself again onto a barrier?

When the socket task calls an entry of the main task, it is blocked until
the main task accepts the call. There is a queue of calls to each entry, so
multiple tasks can await there for a rendezvous. At a time only one
rendezvous is accepted and the corresponding task call is removed from the
queue. Then both tasks engage the rendezvous. Upon the rendezvous the code
"do stuff upon rendezvous" is executed. Any exceptions in this code
propagate into both tasks. When the code completes this or that way the
rendezvous ends, and both tasks continue their execution independently on
each other. I.e. concurrently executing "do stuff after." Here is a
diagram:

    Main             Socket task
      |                  |
do stuff before   do stuff before;
      |                  |
    accept             call
       \                /
      do stuff upon rendezvous (synchronously)
       /                \
do stuff after;    do stuff after
      |                  |

Consider the rendezvous code executed as if both tasks were one.

> Please tell me if I'm not right: every task append it's event
> (data_arrived event) onto the queue.

Rendezvous are better than that, because the queue contains the tasks
themselves. No data are actually copied. If you want to copy data from one
task to another, you simply pass them as a parameter of the call and make a
copy of the parameter during the rendezvous.

> For this reason the main task enters the running state and pops all
> the elements of the queue (events); after having processed all the
> events it will enter the blocked state again. Am I right?

Yes. A task can wait for multiple entries (see the select statement). If
all alternatives of the select are closed, the task is blocked. The
simplest case is just one accept. The task is blocked until nobody calls to
the entry.

>>>> 3. "Queue": socket readers enqueue some data (the queue is implemented
>>>> using a protected object). Other tasks (there could be many) dequeue data
>>>> and do something meaningful with them. There are many kinds of queues for
>>>> different purposes and of different behavior.
> 
> Is it the same of using Mailbox?

Yes, mailbox is a sort of queue. But there are queues of different flavors.
E.g. blocking, non-blocking, waitable on the ends, queues of different
policies at their ends, blackboards etc.

> Roughly speaking, are you suggesting me not to copy the data from
> sockets but accessing the same data through "pointers"?

Not necessarily pointers. I don't know why socket tasks cannot process
their data concurrently. If they need to be synchronized at certain points
why not to do just this. It is a balance which depends on the problem at
hand. In some cases monitors are preferable in other cases they are not.

> Or, are you suggesting me to avoid context switching?

That is the next step. The worst case is both to copy data and to switch
the context. This is what a queue-based solution [*] would do. The best
case is same data same context. BUT, as always, "premature optimization is
the root ..." etc. Solve the problem in the simplest way, only if the
performance is poor consider other solutions.

-----
* Which does not do processing at the context of a protected action.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



  parent reply	other threads:[~2011-12-13 15:39 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-12-10 20:43 Interrupts handling in ADA Ada @ BRL
2011-12-10 21:13 ` Vinzent Hoefler
2011-12-10 22:09 ` Niklas Holsti
2011-12-10 22:27 ` Simon Wright
2011-12-11 20:21   ` Martin Dowie
2011-12-13 13:51     ` Ada BRL
2011-12-13 23:18       ` Martin Dowie
2011-12-13 14:11     ` Niklas Holsti
2011-12-13 14:54       ` Simon Wright
2011-12-13 15:06         ` Ada BRL
2011-12-13 21:49           ` Niklas Holsti
2011-12-13 23:18       ` Martin Dowie
2011-12-13 12:47   ` Ada BRL
2011-12-13 15:07     ` Simon Wright
2011-12-13 15:23       ` Ada BRL
2011-12-13 18:14         ` Simon Wright
2011-12-13 18:56           ` Ada BRL
2011-12-13 19:56           ` Bill Findlay
2011-12-13 22:15         ` Niklas Holsti
2011-12-13 15:34       ` Simon Wright
2011-12-13 17:55         ` Ada BRL
2011-12-13 18:18           ` Dmitry A. Kazakov
2011-12-13 19:01             ` Ada BRL
2011-12-13 19:58               ` Dmitry A. Kazakov
2011-12-13 18:24           ` Simon Wright
2011-12-11  0:15 ` Jeffrey Carter
2011-12-13 12:53   ` Ada BRL
2011-12-11  9:23 ` Dmitry A. Kazakov
2011-12-13 13:11   ` Ada BRL
2011-12-13 14:04     ` Dmitry A. Kazakov
2011-12-13 14:51       ` Ada BRL
2011-12-13 15:02         ` Ada BRL
2011-12-13 15:39         ` Dmitry A. Kazakov [this message]
2011-12-13 18:51           ` Ada BRL
2011-12-13 19:51             ` Dmitry A. Kazakov
2011-12-13 23:32             ` georg bauhaus
2011-12-11 12:04 ` Georg Bauhaus
2011-12-13 14:08   ` Ada BRL
2011-12-12  3:19 ` anon
2011-12-12  9:12   ` Niklas Holsti
2011-12-13 13:36     ` Ada BRL
2011-12-12 15:23   ` björn lundin
2011-12-13 13:38     ` Ada BRL
2011-12-13 13:56       ` Ludovic Brenta
2011-12-13 14:10         ` Ada BRL
2011-12-13 13:31   ` Ada BRL
replies disabled

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