comp.lang.ada
 help / color / mirror / Atom feed
* task synchronization and activation
@ 2005-02-19 15:11 Evangelista Sami
  2005-02-19 16:11 ` Martin Krischik
  2005-02-21  8:50 ` Jean-Pierre Rosen
  0 siblings, 2 replies; 12+ messages in thread
From: Evangelista Sami @ 2005-02-19 15:11 UTC (permalink / raw)


Hello all

Why does a task have to wait that all the tasks it created are
activated before
executing? I am thinking of point 9.2.5 of the RM :

"The task that created the new tasks and initiated their activations
(the activator) is blocked until all of these activations complete
(successfully or not)."

I can understand that a master has to wait for the tasks he created
before finalizing since in the other case it could "free" some memory
needed by its children.
But i cannot see why this synchronisation after activation is
necessary. What is the technical reason?

Thanks for any help

Sami



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: task synchronization and activation
  2005-02-19 15:11 task synchronization and activation Evangelista Sami
@ 2005-02-19 16:11 ` Martin Krischik
  2005-02-19 18:11   ` Ed Falis
  2005-02-19 20:05   ` Robert A Duff
  2005-02-21  8:50 ` Jean-Pierre Rosen
  1 sibling, 2 replies; 12+ messages in thread
From: Martin Krischik @ 2005-02-19 16:11 UTC (permalink / raw)


Evangelista Sami wrote:

> Hello all
> 
> Why does a task have to wait that all the tasks it created are
> activated before
> executing? I am thinking of point 9.particulare RM :
> 
> "The task that created the new tasks and initiated their activations
> (the activator) is blocked until all of these activations complete
> (successfully or not)."
> 
> I can understand that a master has to wait for the tasks he created
> before finalizing since in the other case it could "free" some memory
> needed by its children.
> But i cannot see why this synchronisation after activation is
> necessary. What is the technical reason?

So you can make the first rendezvous with that task. It all depends on the
actual implementation but every task need some internal house keeping
informations and data structures for inter process comunication and they
need to be - savely - initialzed.

Martin
-- 
mailto://krischik@users.sourceforge.net
Ada programming at: http://ada.krischik.com




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: task synchronization and activation
  2005-02-19 16:11 ` Martin Krischik
@ 2005-02-19 18:11   ` Ed Falis
  2005-02-19 20:05   ` Robert A Duff
  1 sibling, 0 replies; 12+ messages in thread
From: Ed Falis @ 2005-02-19 18:11 UTC (permalink / raw)


If I remember my early Ada philosopy rightly (and I don't claim that I  
do), the idea behind the synchronization of the master with the tasks it  
declares is that the latter are considered "servants" of the declaring  
task.  So the idea is for the servants to be ready to work when the master  
begins its real processing (statement list).

- Ed



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: task synchronization and activation
  2005-02-19 16:11 ` Martin Krischik
  2005-02-19 18:11   ` Ed Falis
@ 2005-02-19 20:05   ` Robert A Duff
  2005-02-20 10:47     ` Martin Krischik
  2005-02-21 19:25     ` Dmitry A. Kazakov
  1 sibling, 2 replies; 12+ messages in thread
From: Robert A Duff @ 2005-02-19 20:05 UTC (permalink / raw)


Martin Krischik <martin@krischik.com> writes:

> Evangelista Sami wrote:
> 
> > Hello all
> > 
> > Why does a task have to wait that all the tasks it created are
> > activated before
> > executing? I am thinking of point 9.particulare RM :
> > 
> > "The task that created the new tasks and initiated their activations
> > (the activator) is blocked until all of these activations complete
> > (successfully or not)."
> > 
> > I can understand that a master has to wait for the tasks he created
> > before finalizing since in the other case it could "free" some memory
> > needed by its children.
> > But i cannot see why this synchronisation after activation is
> > necessary. What is the technical reason?
> 
> So you can make the first rendezvous with that task. It all depends on the
> actual implementation but every task need some internal house keeping
> informations and data structures for inter process comunication and they
> need to be - savely - initialzed.

I don't really agree with that.  For one thing, two tasks that are
activated together can (try to) rendezvous with each other.  So they
have to be prepared for entry calls coming in as soon as they are
activated.  (Of course, these entry calls wait until an appropriate
accept statement.)  So whatever internal housekeeping data structures
are needed must be initialized by the activator (probably during task
*creation*), before activating them.

For another thing, the activator waits until the tasks reach their
"begin".  What's so different about the Ada code before and after the
"begin"?  And the tasks don't wait for each other to *all* reach their
"begin"s -- just the activator waits.

So my answer to Evangelista Sami's question is, "There is no good reason
for this design."  At least, I can't think of one.  This extra
synchronization is just a waste of time, as far as I can tell.

One possibility is that the original designers were thinking about the
fact that exceptions that occur before the "begin" can't be handled.
But I don't see why that makes any real difference.

- Bob



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: task synchronization and activation
  2005-02-19 20:05   ` Robert A Duff
@ 2005-02-20 10:47     ` Martin Krischik
  2005-02-21 19:25     ` Dmitry A. Kazakov
  1 sibling, 0 replies; 12+ messages in thread
From: Martin Krischik @ 2005-02-20 10:47 UTC (permalink / raw)


Robert A Duff wrote:

> Martin Krischik <martin@krischik.com> writes:
> One possibility is that the original designers were thinking about the
> fact that exceptions that occur before the "begin" can't be handled.
> But I don't see why that makes any real difference.

AFAIK an exception happen before begin go back to the originator task. I at
least had lot's of fun with exeptions raised in one task and caught in
another.

Martin
-- 
mailto://krischik@users.sourceforge.net
Ada programming at: http://ada.krischik.com




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: task synchronization and activation
  2005-02-19 15:11 task synchronization and activation Evangelista Sami
  2005-02-19 16:11 ` Martin Krischik
@ 2005-02-21  8:50 ` Jean-Pierre Rosen
  2005-02-21 21:55   ` Robert A Duff
  1 sibling, 1 reply; 12+ messages in thread
From: Jean-Pierre Rosen @ 2005-02-21  8:50 UTC (permalink / raw)


Evangelista Sami a �crit :
> Hello all
> 
> Why does a task have to wait that all the tasks it created are
> activated before
> executing? I am thinking of point 9.2.5 of the RM :
> 
> "The task that created the new tasks and initiated their activations
> (the activator) is blocked until all of these activations complete
> (successfully or not)."
> 
> I can understand that a master has to wait for the tasks he created
> before finalizing since in the other case it could "free" some memory
> needed by its children.
> But i cannot see why this synchronisation after activation is
> necessary. What is the technical reason?
> 
It has to do with exceptions at elaboration.

When a task is started, it first elaborates its declarative part. If 
exceptions are raised during this elaboration, they cannot be handled by 
the task itself, therefore it is necessary to notify *someone*, and the 
obvious "someone" is the activator. However, we don't want to have 
asynchronous exceptions, therefore the activator has to wait that all 
subtasks are (correctly) activated.

Differently said: when an activator reaches the first statement after 
the begin, it is guaranteed that all subtasks have been correctly 
activated; otherwise, Tasking_Error is raised after begin (so it can be 
handled locally), but before the first statement.

-- 
---------------------------------------------------------
            J-P. Rosen (rosen@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: task synchronization and activation
  2005-02-19 20:05   ` Robert A Duff
  2005-02-20 10:47     ` Martin Krischik
@ 2005-02-21 19:25     ` Dmitry A. Kazakov
  1 sibling, 0 replies; 12+ messages in thread
From: Dmitry A. Kazakov @ 2005-02-21 19:25 UTC (permalink / raw)


On 19 Feb 2005 15:05:19 -0500, Robert A Duff wrote:

> So my answer to Evangelista Sami's question is, "There is no good reason
> for this design."  At least, I can't think of one.  This extra
> synchronization is just a waste of time, as far as I can tell.
> 
> One possibility is that the original designers were thinking about the
> fact that exceptions that occur before the "begin" can't be handled.
> But I don't see why that makes any real difference.

Maybe initially they wished not to have 9.2(7):

"An entry of a task can be called before the task has been activated."
 
Later on they added it, but forgot to remove the limitation...

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



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: task synchronization and activation
  2005-02-21  8:50 ` Jean-Pierre Rosen
@ 2005-02-21 21:55   ` Robert A Duff
  2005-02-22  0:01     ` Randy Brukardt
  2005-02-22  7:17     ` Jean-Pierre Rosen
  0 siblings, 2 replies; 12+ messages in thread
From: Robert A Duff @ 2005-02-21 21:55 UTC (permalink / raw)


Jean-Pierre Rosen <rosen@adalog.fr> writes:

> Evangelista Sami a �crit :
> > Hello all
> > Why does a task have to wait that all the tasks it created are
> > activated before
> > executing? I am thinking of point 9.2.5 of the RM :
> > "The task that created the new tasks and initiated their activations
> > (the activator) is blocked until all of these activations complete
> > (successfully or not)."
> > I can understand that a master has to wait for the tasks he created
> > before finalizing since in the other case it could "free" some memory
> > needed by its children.
> > But i cannot see why this synchronisation after activation is
> > necessary. What is the technical reason?
> >
> It has to do with exceptions at elaboration.
> 
> When a task is started, it first elaborates its declarative part. If
> exceptions are raised during this elaboration, they cannot be handled by
> the task itself, therefore it is necessary to notify *someone*, and the
> obvious "someone" is the activator. However, we don't want to have
> asynchronous exceptions, therefore the activator has to wait that all
> subtasks are (correctly) activated.

I can believe that that was the reasoning of the Ada 83 designers.
But I still don't quite agree with it.

For one thing, if you want to handle exceptions in the decl part,
just change this:

    task body T is
        ... -- possible exception here?
    begin
        ...
    end T;

to this:

    task body T is
    begin
        declare
            ... -- possible exception here?
        begin
            ...
        end;
    exception
        ...
    end T;

and now the task can handle it (because it's no longer in the task's
declarative part).  So it's a case of "Doctor, it hurts when I...."
"So don't do that."  ;-)

For another thing, what about exceptions in the exception handler part
of a task?  Those can't be handled by the task either, so they get
dropped on the floor -- nobody gets notified.  And in this case,
there is no 100% reliable workaround -- you can wrap that handler
in another block statement with another handler, but then what about
the 'nother handler?  There's an infinite regress.  You could carefully
inspect the outermost handler of a task, and make sure it doesn't have
any bugs (good idea!) -- but it could still get Storage_Error.

- Bob



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: task synchronization and activation
  2005-02-21 21:55   ` Robert A Duff
@ 2005-02-22  0:01     ` Randy Brukardt
  2005-02-22  7:17     ` Jean-Pierre Rosen
  1 sibling, 0 replies; 12+ messages in thread
From: Randy Brukardt @ 2005-02-22  0:01 UTC (permalink / raw)


"Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message
news:wcchdk54lxu.fsf@shell01.TheWorld.com...
...
> For another thing, what about exceptions in the exception handler part
> of a task?  Those can't be handled by the task either, so they get
> dropped on the floor -- nobody gets notified.  And in this case,
> there is no 100% reliable workaround -- you can wrap that handler
> in another block statement with another handler, but then what about
> the 'nother handler?  There's an infinite regress.  You could carefully
> inspect the outermost handler of a task, and make sure it doesn't have
> any bugs (good idea!) -- but it could still get Storage_Error.

In Ada 2005, you can use a task termination handler to detect this. But that
too isn't perfect, because it can't guarantee to work in the face of a
Storage_Error (nothing can, really, and that is the most common problem in
my experience).

                   Randy.







^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: task synchronization and activation
  2005-02-21 21:55   ` Robert A Duff
  2005-02-22  0:01     ` Randy Brukardt
@ 2005-02-22  7:17     ` Jean-Pierre Rosen
  2005-02-23  2:24       ` Robert A Duff
  1 sibling, 1 reply; 12+ messages in thread
From: Jean-Pierre Rosen @ 2005-02-22  7:17 UTC (permalink / raw)


Robert A Duff a �crit :
[...]
> I can believe that that was the reasoning of the Ada 83 designers.
> But I still don't quite agree with it.
> 
> For one thing, if you want to handle exceptions in the decl part,
> just change this:
> 
>     task body T is
>         ... -- possible exception here?
>     begin
>         ...
>     end T;
> 
> to this:
> 
>     task body T is
>     begin
>         declare
>             ... -- possible exception here?
>         begin
>             ...
>         end;
>     exception
>         ...
>     end T;
> 
> and now the task can handle it (because it's no longer in the task's
> declarative part).  So it's a case of "Doctor, it hurts when I...."
> "So don't do that."  ;-)

It is not the same thing *at all*. Here, you are putting the 
responsibility on the task's side, but the issue is to be safe from the 
caller's point of view.

Let's look at it differently. A program unit needs some subtasks to do 
its job. If the subtasks cannot be started for any reason (including 
storage_error), then the program unit cannot work, and it'd better be 
noticed of that; most likely, the program unit will raise an exception 
or find a fall-back strategy. Since asynchronous exceptions are horrible 
(Java did that mistake, and had to back-up), this must happen 
synchronously, and the logical point is just before executing any statement.

Now, you can argue that the subtasks may fail at any later time; that's 
true, and Tasking_Error may be raised for any interaction. However, 
failing activation is basically not having the resources to start the 
servers, and is a much more severe condition.


-- 
---------------------------------------------------------
            J-P. Rosen (rosen@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: task synchronization and activation
  2005-02-22  7:17     ` Jean-Pierre Rosen
@ 2005-02-23  2:24       ` Robert A Duff
  2005-02-23  7:58         ` Martin Krischik
  0 siblings, 1 reply; 12+ messages in thread
From: Robert A Duff @ 2005-02-23  2:24 UTC (permalink / raw)


Jean-Pierre Rosen <rosen@adalog.fr> writes:

> Robert A Duff a �crit :
> [...]
> > I can believe that that was the reasoning of the Ada 83 designers.
> > But I still don't quite agree with it.
> > For one thing, if you want to handle exceptions in the decl part,
> > just change this:
> >     task body T is
> >         ... -- possible exception here?
> >     begin
> >         ...
> >     end T;
> > to this:
> >     task body T is
> >     begin
> >         declare
> >             ... -- possible exception here?
> >         begin
> >             ...
> >         end;
> >     exception
> >         ...
> >     end T;
> > and now the task can handle it (because it's no longer in the task's
> > declarative part).  So it's a case of "Doctor, it hurts when I...."
> > "So don't do that."  ;-)
> 
> It is not the same thing *at all*. Here, you are putting the
> responsibility on the task's side, but the issue is to be safe from the
> caller's point of view.
> 
> Let's look at it differently. A program unit needs some subtasks to do
> its job. If the subtasks cannot be started for any reason (including
> storage_error), then the program unit cannot work, and it'd better be
> noticed of that; most likely, the program unit will raise an exception
> or find a fall-back strategy. Since asynchronous exceptions are horrible
> (Java did that mistake, and had to back-up), this must happen
> synchronously, and the logical point is just before executing any
> statement.
> 
> Now, you can argue that the subtasks may fail at any later time;

Yes, I do argue exactly that.  ;-)

>... that's
> true, and Tasking_Error may be raised for any interaction. However,
> failing activation is basically not having the resources to start the
> servers, and is a much more severe condition.

Failing activation (i.e. raising an exception before "begin") could be
due to lack of resources, or a bug, or any other cause of exceptions.
Exceptions *after* "begin" can also be caused by any of these --
including running out of resources.  So I don't see any reason to
believe that exceptions before the begin are more severe, or deserve an
automatic means of notification -- let the programmer decide which
exceptions are severe, and how/who should be notified.

Actually, I'd say exceptions in an exception handler are typically more
severe than others, because they represent failure of a failure-recovery
mechanism.  But I still think the programmer, not the language designer,
should make such decisions.

Anyway, passing the "begin" is no indication that the task is ready to
go.  Putting code before and after "begin" is determined by all kinds of
unrelated issues (like if you want to call a subprogram that creates a
String, you normally have to use a function result, rather than an 'out'
parameter, so it comes before "begin", whereas if you want to initialize
a variable with a loop, that comes after "begin").  A task is ready to
receive entry calls when it reaches an accept -- "begin" is irrelevant.

- Bob



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: task synchronization and activation
  2005-02-23  2:24       ` Robert A Duff
@ 2005-02-23  7:58         ` Martin Krischik
  0 siblings, 0 replies; 12+ messages in thread
From: Martin Krischik @ 2005-02-23  7:58 UTC (permalink / raw)


Robert A Duff wrote:

> Jean-Pierre Rosen <rosen@adalog.fr> writes:
> 
>> Robert A Duff a ï¿œcrit :
>> [...]
>> > I can believe that that was the reasoning of the Ada 83 designers.
>> > But I still don't quite agree with it.
>> > For one thing, if you want to handle exceptions in the decl part,
>> > just change this:
>> >     task body T is
>> >         ... -- possible exception here?
>> >     begin
>> >         ...
>> >     end T;
>> > to this:
>> >     task body T is
>> >     begin
>> >         declare
>> >             ... -- possible exception here?
>> >         begin
>> >             ...
>> >         end;
>> >     exception
>> >         ...
>> >     end T;
>> > and now the task can handle it (because it's no longer in the task's
>> > declarative part).  So it's a case of "Doctor, it hurts when I...."
>> > "So don't do that."  ;-)
>> 
>> It is not the same thing *at all*. Here, you are putting the
>> responsibility on the task's side, but the issue is to be safe from the
>> caller's point of view.
>> 
>> Let's look at it differently. A program unit needs some subtasks to do
>> its job. If the subtasks cannot be started for any reason (including
>> storage_error), then the program unit cannot work, and it'd better be
>> noticed of that; most likely, the program unit will raise an exception
>> or find a fall-back strategy. Since asynchronous exceptions are horrible
>> (Java did that mistake, and had to back-up), this must happen
>> synchronously, and the logical point is just before executing any
>> statement.
>> 
>> Now, you can argue that the subtasks may fail at any later time;
> 
> Yes, I do argue exactly that.  ;-)
> 
>>... that's
>> true, and Tasking_Error may be raised for any interaction. However,
>> failing activation is basically not having the resources to start the
>> servers, and is a much more severe condition.
> 
> Failing activation (i.e. raising an exception before "begin") could be
> due to lack of resources, or a bug, or any other cause of exceptions.
> Exceptions *after* "begin" can also be caused by any of these --
> including running out of resources.  So I don't see any reason to
> believe that exceptions before the begin are more severe, or deserve an
> automatic means of notification -- let the programmer decide which
> exceptions are severe, and how/who should be notified.

Exceptions after the begin can be handled by the task itself while
exceptions before can not. Look at the following simple no task example:

Outer :
declare
    Inner :
    declare
        type T is access ....

        A : T := new ...
        B : T;
    begin
        B := new ....
    exception
        when Storage_Error =>  
        -- hande new B
    end Inner;
exception
    when Storage_Error => 
    -- handle new A
end Outer;

> Actually, I'd say exceptions in an exception handler are typically more
> severe than others, because they represent failure of a failure-recovery
> mechanism.  But I still think the programmer, not the language designer,
> should make such decisions.

There is an important difference in exceptions handling for statemens before
and after begin. And with the current solution both task and no task
environments are consistant with each other. Change one and you have to
change the other as well.

And yes, I have quite a few procedures with start with:

Try :
declare

for precicly that reason. If you don't want the activator task to wait you
have to to the same as when you want a write "no raise" procedure:

task body T
is
begin
  Try:
  declare
     ....
  exception
     ....
  end Try;
end T;

Sidenote: I usualy need "no raise" procedures for interfacing with C.

> Anyway, passing the "begin" is no indication that the task is ready to
> go.  Putting code before and after "begin" is determined by all kinds of
> unrelated issues (like if you want to call a subprogram that creates a
> String, you normally have to use a function result, rather than an 'out'
> parameter, so it comes before "begin", whereas if you want to initialize
> a variable with a loop, that comes after "begin").  A task is ready to
> receive entry calls when it reaches an accept -- "begin" is irrelevant.

But it is all about exception handling. And it is consitant with procedures
and functions as it is.

Martin
-- 
mailto://krischik@users.sourceforge.net
Ada programming at: http://ada.krischik.com




^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2005-02-23  7:58 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-02-19 15:11 task synchronization and activation Evangelista Sami
2005-02-19 16:11 ` Martin Krischik
2005-02-19 18:11   ` Ed Falis
2005-02-19 20:05   ` Robert A Duff
2005-02-20 10:47     ` Martin Krischik
2005-02-21 19:25     ` Dmitry A. Kazakov
2005-02-21  8:50 ` Jean-Pierre Rosen
2005-02-21 21:55   ` Robert A Duff
2005-02-22  0:01     ` Randy Brukardt
2005-02-22  7:17     ` Jean-Pierre Rosen
2005-02-23  2:24       ` Robert A Duff
2005-02-23  7:58         ` Martin Krischik

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