comp.lang.ada
 help / color / mirror / Atom feed
* How to tell whether program finalization can be suppressed
@ 2017-12-01 21:39 Simon Wright
  2017-12-01 22:43 ` Randy Brukardt
                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Simon Wright @ 2017-12-01 21:39 UTC (permalink / raw)


In Cortex GNAT RTS[1] (a Ravenscar RTS), I've wanted to support
finalization (at present, I have the possibly GNAT-specific
restriction No_Finalization).

Unfortunately, as reported in PR66205[2], without No_Finalization and
in the presence of other RTS-limiting features, gnatbind generates
binding code which won't compile.

I need to find a way of determining whether the RTS actually needs
program-level finalization (that is, finalization called on program
exit), because that's where the bad code is generated.

Clearly, if the program never exits, there will be no need for
program-level finalization.

Amongst other things, I can test for specific restrictions, and I'm
wondering whether No_Task_Termination would be appropriate for this?
(I'm assuming that the environment task mustn't terminate, even if the
main program exits; and in this RTS, exceptions can't be propagated).

[1] https://github.com/simonjwright/cortex-gnat-rts
[2] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66205


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

* Re: How to tell whether program finalization can be suppressed
  2017-12-01 21:39 How to tell whether program finalization can be suppressed Simon Wright
@ 2017-12-01 22:43 ` Randy Brukardt
  2017-12-02  9:48   ` Simon Wright
  2017-12-02 11:12   ` AdaMagica
  2017-12-02  3:08 ` Robert Eachus
  2017-12-27 15:49 ` Simon Wright
  2 siblings, 2 replies; 15+ messages in thread
From: Randy Brukardt @ 2017-12-01 22:43 UTC (permalink / raw)


"Simon Wright" <simon@pushface.org> wrote in message 
news:lyzi729lh2.fsf@pushface.org...
...
> Amongst other things, I can test for specific restrictions, and I'm
> wondering whether No_Task_Termination would be appropriate for this?
> (I'm assuming that the environment task mustn't terminate, even if the
> main program exits; and in this RTS, exceptions can't be propagated).

I don't know enough about the details of GNAT to say anything useful about 
it specifically, but the above seems confused from an Ada perspective. When 
the main program exits, of course the environment task completes and then 
terminates. It's the completion of the environment task that starts 
library-level finalization. (Indeed, you can use Ada.Task_Identification to 
figure out that this is happening -- that is how Claw shuts down its tasks, 
otherwise they would wait forever for operations that aren't ever going to 
happen.) The termination of the environment tasks causes the entire program 
to exit (normally or via exception).

In an embedded system that is supposed to run forever, one would expect that 
the main subprogram would never exit. If it did exit, the system would shut 
itself off, which probably would lead to task waiting and then library-level 
finalization. After that, one would try to restart the system from scratch. 
I suppose someone could build a system that did something else on such an 
exit (which always represents a catostrophic failure), but it wouldn't be 
very Ada-like - finalization would not get performed on objects that are 
expecting that (potentially leaving things in unusual states). Such a system 
would have to start-up making no assumptions at all, even the ones that 
usually could be made at power-up -- which sounds painful.

                                         Randy.


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

* Re: How to tell whether program finalization can be suppressed
  2017-12-01 21:39 How to tell whether program finalization can be suppressed Simon Wright
  2017-12-01 22:43 ` Randy Brukardt
@ 2017-12-02  3:08 ` Robert Eachus
  2017-12-27 15:49 ` Simon Wright
  2 siblings, 0 replies; 15+ messages in thread
From: Robert Eachus @ 2017-12-02  3:08 UTC (permalink / raw)


On Friday, December 1, 2017 at 4:39:24 PM UTC-5, Simon Wright wrote:
 
> I need to find a way of determining whether the RTS actually needs
> program-level finalization (that is, finalization called on program
> exit), because that's where the bad code is generated.
> 
> Clearly, if the program never exits, there will be no need for
> program-level finalization.
> 
> Amongst other things, I can test for specific restrictions, and I'm
> wondering whether No_Task_Termination would be appropriate for this?
> (I'm assuming that the environment task mustn't terminate, even if the
> main program exits; and in this RTS, exceptions can't be propagated).

I have some programs where all the work is done in worker tasks, and the main program just needs to stay around until they all finish.  What I always seem to end up with, because I need some way of determining that the program is finished is something like this:

procedure Main is
begin
  --get a timestamp, and print out that the program is running.
  --fire off lots of library-level tasks, don't want them to depend on
  --the main program.
  declare
    task Monitor is
      entry Killer;
    end Monitor;
 
    task body Monitor is
    begin
      select
        accept Killer;
      or
        terminate;
      end select;
    end Monitor;
  end;
  -- print a timestamp...
end Main;

The worker tasks don't include terminate alternatives, they only call Killer in extreme error cases like can't open data file, network errors, etc.  When the last library level task goes away, the terminate alternative is selected.

Sounds like this sort of structure would avoid your bug.


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

* Re: How to tell whether program finalization can be suppressed
  2017-12-01 22:43 ` Randy Brukardt
@ 2017-12-02  9:48   ` Simon Wright
  2017-12-04 20:18     ` Randy Brukardt
  2017-12-04 22:41     ` Simon Wright
  2017-12-02 11:12   ` AdaMagica
  1 sibling, 2 replies; 15+ messages in thread
From: Simon Wright @ 2017-12-02  9:48 UTC (permalink / raw)


"Randy Brukardt" <randy@rrsoftware.com> writes:

> "Simon Wright" <simon@pushface.org> wrote in message
> news:lyzi729lh2.fsf@pushface.org...
> ...
>> Amongst other things, I can test for specific restrictions, and I'm
>> wondering whether No_Task_Termination would be appropriate for this?
>> (I'm assuming that the environment task mustn't terminate, even if
>> the main program exits; and in this RTS, exceptions can't be
>> propagated).
[...]
> In an embedded system that is supposed to run forever, one would
> expect that the main subprogram would never exit. If it did exit, the
> system would shut itself off, which probably would lead to task
> waiting and then library-level finalization. After that, one would try
> to restart the system from scratch.  I suppose someone could build a
> system that did something else on such an exit (which always
> represents a catostrophic failure), but it wouldn't be very Ada-like -
> finalization would not get performed on objects that are expecting
> that (potentially leaving things in unusual states). Such a system
> would have to start-up making no assumptions at all, even the ones
> that usually could be made at power-up -- which sounds painful.

I think this was a red herring - sorry. The thinking was, this is a
Ravenscar RTS; Ravenscar includes No_Task_Termination; the environment
task is a task; therefore it's not allowed to terminate.

In any case, ARM 10.2(25)[1] doesn't appear to say that the main program
shouldn't exit, or that if it does the system should shut down.

[as a side remark, I take it that 10.2(10)ff are such that the
implementation is expected to behave 'as-if'?]

But of course the main program in an embedded system won't exit.  System
termination in a drone running on a microcontroller with 1M flash and
192K RAM, with No_Exception_Propagation, will happen because of some
exception resulting in a last-chance handler getting called.

I take your point about things being left in unusual states. At present,
the Certyflie[2] software resets the motors and leaves the aircraft to
tumble to the ground (normal takeoff weight 27g: max 42g, so not very
hazardous). The chance of restoring normal operation to the point where
the drone can do a managed landing rather than just crashing is slender.

[1] http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-10-2.html#p25
[2] https://github.com/AdaCore/Certyflie


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

* Re: How to tell whether program finalization can be suppressed
  2017-12-01 22:43 ` Randy Brukardt
  2017-12-02  9:48   ` Simon Wright
@ 2017-12-02 11:12   ` AdaMagica
  2017-12-03 17:16     ` Robert Eachus
  1 sibling, 1 reply; 15+ messages in thread
From: AdaMagica @ 2017-12-02 11:12 UTC (permalink / raw)


Am Freitag, 1. Dezember 2017 23:43:25 UTC+1 schrieb Randy Brukardt:
> When 
> the main program exits, of course the environment task completes and then 
> terminates. It's the completion of the environment task that starts 
> library-level finalization. (Indeed, you can use Ada.Task_Identification to 
> figure out that this is happening -- that is how Claw shuts down its tasks, 
> otherwise they would wait forever for operations that aren't ever going to 
> happen.) The termination of the environment tasks causes the entire program 
> to exit (normally or via exception).

Just to refresh my memory:
The main subprogram is the master of any library tasks. It may be empty (I just confirmed this with a little test) and thus does not exit until all library tasks are terminated or waiting on a terminate alternative.

with Lib;  -- in the elaboration sequence, there are some tasks
procedure Main is
begin
  null;  -- waiting here for tasks to terminate
end Main;


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

* Re: How to tell whether program finalization can be suppressed
  2017-12-02 11:12   ` AdaMagica
@ 2017-12-03 17:16     ` Robert Eachus
  2017-12-04 11:58       ` AdaMagica
  0 siblings, 1 reply; 15+ messages in thread
From: Robert Eachus @ 2017-12-03 17:16 UTC (permalink / raw)


On Saturday, December 2, 2017 at 6:12:13 AM UTC-5, AdaMagica wrote:
> 
> Just to refresh my memory:
> The main subprogram is the master of any library tasks. It may be empty (I just confirmed this with a little test) and thus does not exit until all library tasks are terminated or waiting on a terminate alternative.
> 
> with Lib;  -- in the elaboration sequence, there are some tasks
> procedure Main is
> begin
>   null;  -- waiting here for tasks to terminate
> end Main;

No, the environment task is the master of library level tasks.  It doesn't matter in your test case since the waiting will occur after the main program completes.  If the desire is not to wait after the main program finishes, end it with an abort statement.  Nicer means of program shutdown when the main program completes are left as an exercise for the reader.

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

* Re: How to tell whether program finalization can be suppressed
  2017-12-03 17:16     ` Robert Eachus
@ 2017-12-04 11:58       ` AdaMagica
  2017-12-04 14:36         ` Robert Eachus
  2017-12-04 20:22         ` Randy Brukardt
  0 siblings, 2 replies; 15+ messages in thread
From: AdaMagica @ 2017-12-04 11:58 UTC (permalink / raw)


Am Sonntag, 3. Dezember 2017 18:16:47 UTC+1 schrieb Robert Eachus:
> On Saturday, December 2, 2017 at 6:12:13 AM UTC-5, AdaMagica wrote:
> > 
> > Just to refresh my memory:
> > The main subprogram is the master of any library tasks. It may be empty (I just confirmed this with a little test) and thus does not exit until all library tasks are terminated or waiting on a terminate alternative.
> > 
> > with Lib;  -- in the elaboration sequence, there are some tasks
> > procedure Main is
> > begin
> >   null;  -- waiting here for tasks to terminate
> > end Main;
> 
> No, the environment task is the master of library level tasks.  It doesn't matter in your test case since the waiting will occur after the main program completes.  If the desire is not to wait after the main program finishes, end it with an abort statement.  Nicer means of program shutdown when the main program completes are left as an exercise for the reader.

But that's what Randy wrote:
"When the main program exits, of course the environment task completes and then
terminates. It's the completion of the environment task that starts library-level finalization."
So what did he want to say? Main resp. env task exits, completes, terminates... Normally, Randy is precise in what he says.

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

* Re: How to tell whether program finalization can be suppressed
  2017-12-04 11:58       ` AdaMagica
@ 2017-12-04 14:36         ` Robert Eachus
  2017-12-04 17:16           ` AdaMagica
  2017-12-04 20:22         ` Randy Brukardt
  1 sibling, 1 reply; 15+ messages in thread
From: Robert Eachus @ 2017-12-04 14:36 UTC (permalink / raw)


On Monday, December 4, 2017 at 6:58:48 AM UTC-5, AdaMagica wrote:
> Am Sonntag, 3. Dezember 2017 18:16:47 UTC+1 schrieb Robert Eachus:
> > On Saturday, December 2, 2017 at 6:12:13 AM UTC-5, AdaMagica wrote:
> > > 
> > > Just to refresh my memory:
> > > The main subprogram is the master of any library tasks. It may be empty (I just confirmed this with a little test) and thus does not exit until all library tasks are terminated or waiting on a terminate alternative.
> > > 
> > > with Lib;  -- in the elaboration sequence, there are some tasks
> > > procedure Main is
> > > begin
> > >   null;  -- waiting here for tasks to terminate
> > > end Main;
> > 
> > No, the environment task is the master of library level tasks...
> 
> But that's what Randy wrote:
> "When the main program exits, of course the environment task completes and then
> terminates. It's the completion of the environment task that starts library-level finalization."
> So what did he want to say? Main resp. env task exits, completes, terminates... Normally, Randy is precise in what he says.

I wasn't disagreeing with Randy, except maybe to make it clearer that library level tasks can continue to run after the main program completes.  I was disagreeing with your statement that the main program is the master of library-level tasks.  Didn't matter in your example, but I could probably gin up an example.  Hmm.  Something with Ada.Text_IO.File_Types and reassignment of Current_Output? I usually keep the main program around to print out a message when the program completes successfully, but that's personal style.


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

* Re: How to tell whether program finalization can be suppressed
  2017-12-04 14:36         ` Robert Eachus
@ 2017-12-04 17:16           ` AdaMagica
  2017-12-04 18:21             ` Jeffrey R. Carter
  2017-12-04 20:25             ` Randy Brukardt
  0 siblings, 2 replies; 15+ messages in thread
From: AdaMagica @ 2017-12-04 17:16 UTC (permalink / raw)


Am Montag, 4. Dezember 2017 15:36:18 UTC+1 schrieb Robert Eachus:
> > But that's what Randy wrote:
> > "When the main program exits, of course the environment task completes and then
> > terminates. It's the completion of the environment task that starts library-level finalization."
> > So what did he want to say? Main resp. env task exits, completes, terminates... Normally, Randy is precise in what he says.
> 
> I wasn't disagreeing with Randy, except maybe to make it clearer that library level tasks can continue to run after the main program completes.  I was disagreeing with your statement that the main program is the master of library-level tasks.  Didn't matter in your example, but I could probably gin up an example.  Hmm.  Something with Ada.Text_IO.File_Types and reassignment of Current_Output? I usually keep the main program around to print out a message when the program completes successfully, but that's personal style.

You don't get my point. Randy said, when the main exits, the env task completes, and that's not true as my example shows.

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

* Re: How to tell whether program finalization can be suppressed
  2017-12-04 17:16           ` AdaMagica
@ 2017-12-04 18:21             ` Jeffrey R. Carter
  2017-12-04 20:25             ` Randy Brukardt
  1 sibling, 0 replies; 15+ messages in thread
From: Jeffrey R. Carter @ 2017-12-04 18:21 UTC (permalink / raw)


On 12/04/2017 06:16 PM, AdaMagica wrote:
> 
> You don't get my point. Randy said, when the main exits, the env task completes, and that's not true as my example shows.

I suspect you're using a different definition of "completes" than the language 
lawyers. I think it means "terminates" to you, but not to them.

-- 
Jeff Carter
"I would never want to belong to any club that
would have someone like me for a member."
Annie Hall
41

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

* Re: How to tell whether program finalization can be suppressed
  2017-12-02  9:48   ` Simon Wright
@ 2017-12-04 20:18     ` Randy Brukardt
  2017-12-04 22:41     ` Simon Wright
  1 sibling, 0 replies; 15+ messages in thread
From: Randy Brukardt @ 2017-12-04 20:18 UTC (permalink / raw)


"Simon Wright" <simon@pushface.org> wrote in message 
news:lylgil9ivj.fsf@pushface.org...
...
> In any case, ARM 10.2(25)[1] doesn't appear to say that the main program
> shouldn't exit, or that if it does the system should shut down.
>
> [as a side remark, I take it that 10.2(10)ff are such that the
> implementation is expected to behave 'as-if'?]

All of the Ada Standard (and any programming language standard, really), is 
"as-if". The standard has nothing to say (and couldn't really say anything) 
about the actual code of the program. So long as a program can't tell that 
the semantics are different than specified, it is OK.

                                Randy.


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

* Re: How to tell whether program finalization can be suppressed
  2017-12-04 11:58       ` AdaMagica
  2017-12-04 14:36         ` Robert Eachus
@ 2017-12-04 20:22         ` Randy Brukardt
  1 sibling, 0 replies; 15+ messages in thread
From: Randy Brukardt @ 2017-12-04 20:22 UTC (permalink / raw)


"AdaMagica" <christ-usch.grein@t-online.de> wrote in message 
news:d9039b0d-993b-49e1-9bde-6a079bddec65@googlegroups.com...
...
>But that's what Randy wrote:
>"When the main program exits, of course the environment task completes
>and then terminates. It's the completion of the environment task that 
>starts
>library-level finalization."

>So what did he want to say? Main resp. env task exits, completes,
>terminates... Normally, Randy is precise in what he says.

I said it right: the main subprogram exits, the environment task completes, 
then terminates. In that order, and those are separate things (read RM 10.2 
for the details). The environment task calls the main subprogram (this 
literally happens in the Janus/Ada compiler, the call is generated by the 
binder, can't speak for other compilers). There's nothing special about the 
main subprogram (there can't be, since Ada doesn't mark it specially at 
all), it's just a normal subprogram called by the environment task.

                                  Randy.


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

* Re: How to tell whether program finalization can be suppressed
  2017-12-04 17:16           ` AdaMagica
  2017-12-04 18:21             ` Jeffrey R. Carter
@ 2017-12-04 20:25             ` Randy Brukardt
  1 sibling, 0 replies; 15+ messages in thread
From: Randy Brukardt @ 2017-12-04 20:25 UTC (permalink / raw)


"AdaMagica" <christ-usch.grein@t-online.de> wrote in message 
news:c07c2ffa-1f0e-418f-b447-986db8ceb343@googlegroups.com...
...
>> I wasn't disagreeing with Randy, except maybe to make it clearer that
>> library level tasks can continue to run after the main program completes.
>>  I was disagreeing with your statement that the main program is the
>> master of library-level tasks.  Didn't matter in your example, but I 
>> could
>> probably gin up an example.  Hmm.  Something with
>> Ada.Text_IO.File_Types and reassignment of Current_Output? I usually
>> keep the main program around to print out a message when the program
>> completes successfully, but that's personal style.
>
>You don't get my point. Randy said, when the main exits, the env task
> completes, and that's not true as my example shows.

??? You need to go back and read the definition of task termination. 
Finalization and task waiting happen *after* a task completes and before it 
terminates (that's why those are separate terms!!!)

                              Randy.


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

* Re: How to tell whether program finalization can be suppressed
  2017-12-02  9:48   ` Simon Wright
  2017-12-04 20:18     ` Randy Brukardt
@ 2017-12-04 22:41     ` Simon Wright
  1 sibling, 0 replies; 15+ messages in thread
From: Simon Wright @ 2017-12-04 22:41 UTC (permalink / raw)


Simon Wright <simon@pushface.org> writes:

> In any case, ARM 10.2(25)[1] doesn't appear to say that the main
> program shouldn't exit, or that if it does the system should shut
> down.

Its last sentence is

  "When the environment task completes (normally or abnormally), it
  waits for the termination of all such tasks, and then finalizes any
  remaining objects of the partition."

So, since I'm developing a Ravenscar RTS, with restrictions
No_Task_Termination and No_Exception_Propagation (GNAT
implementation-defined), the environment task will wait forever and the
final finalization will not happen. Of course, if a task actually exits
(not sure whether GNAT detects this at compile time) or a
not-locally-handled exception occurs, we are in trouble, to the point
where we don't need to worry about final finalization.

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

* Re: How to tell whether program finalization can be suppressed
  2017-12-01 21:39 How to tell whether program finalization can be suppressed Simon Wright
  2017-12-01 22:43 ` Randy Brukardt
  2017-12-02  3:08 ` Robert Eachus
@ 2017-12-27 15:49 ` Simon Wright
  2 siblings, 0 replies; 15+ messages in thread
From: Simon Wright @ 2017-12-27 15:49 UTC (permalink / raw)


Simon Wright <simon@pushface.org> writes:

> In Cortex GNAT RTS[1] (a Ravenscar RTS), I've wanted to support
> finalization (at present, I have the possibly GNAT-specific
> restriction No_Finalization).
>
> Unfortunately, as reported in PR66205[2], without No_Finalization and
> in the presence of other RTS-limiting features, gnatbind generates
> binding code which won't compile.
>
> I need to find a way of determining whether the RTS actually needs
> program-level finalization (that is, finalization called on program
> exit), because that's where the bad code is generated.
>
> Clearly, if the program never exits, there will be no need for
> program-level finalization.
>
> Amongst other things, I can test for specific restrictions, and I'm
> wondering whether No_Task_Termination would be appropriate for this?
> (I'm assuming that the environment task mustn't terminate, even if the
> main program exits; and in this RTS, exceptions can't be propagated).
>
> [1] https://github.com/simonjwright/cortex-gnat-rts
> [2] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66205

To close this thread, which has had many interesting and helpful
responses:

I proposed a patch based on these ideas, which worked for me but wasn't
acceptable for AdaCore; some automated tests failed (I don't know the
details. I guess a Ravenscar program in such a context is allowed to
terminate & finalize itself!).

The working fix turned out to be to tell the compiler that the "standard
library" (not quite sure what that is) is supported (which I don't think
it is): this is the only way to get current gnatbind to generate
compilable code when it sees finalization. Then, one needs additional
dummy variables which would control aspects of a full RTS (e.g. wide
character encoding, locking policy, task dispatching policy, to name but
a few).

Thaks for the help.


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

end of thread, other threads:[~2017-12-27 15:49 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-01 21:39 How to tell whether program finalization can be suppressed Simon Wright
2017-12-01 22:43 ` Randy Brukardt
2017-12-02  9:48   ` Simon Wright
2017-12-04 20:18     ` Randy Brukardt
2017-12-04 22:41     ` Simon Wright
2017-12-02 11:12   ` AdaMagica
2017-12-03 17:16     ` Robert Eachus
2017-12-04 11:58       ` AdaMagica
2017-12-04 14:36         ` Robert Eachus
2017-12-04 17:16           ` AdaMagica
2017-12-04 18:21             ` Jeffrey R. Carter
2017-12-04 20:25             ` Randy Brukardt
2017-12-04 20:22         ` Randy Brukardt
2017-12-02  3:08 ` Robert Eachus
2017-12-27 15:49 ` Simon Wright

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