Version 1.6 of ai12s/ai12-0404-1.txt

Unformatted version of ai12s/ai12-0404-1.txt version 1.6
Other versions for file ai12s/ai12-0404-1.txt

!standard 3.3.1(8.1/5)          20-12-09 AI12-0404-1/06
!standard 3.9.1(14)
!standard 5.6.1(4/5)
!standard D(1)
!standard D.1(15)
!standard D.1(23)
!standard D.3(13)
!standard D.3(13.2/2)
!standard D.3(13.3/2)
!standard D.3(13.4/2)
!standard D.3(13.5/2)
!standard H.7.1(14/5)
!standard H.7.1(17/5)
!standard H.7.1(18/5)
!class binding interpretation 20-10-21
!status Amendment 1-2012 20-10-21
!status WG9 Approved 22-06-22
!status ARG Approved 15-0-0 20-12-09
!status work item 20-10-21
!status received 20-10-21
!priority Low
!difficulty Easy
!qualifier Omission
!subject Presentation issues from Draft 26 review - part 2
!summary
Various wording issues were noted by reviewers of Draft 26.
!question
(1) H.7.1(17/5) says:
Within an operation to which a Dispatching aspect applies, any dispatching call that does not match any dispatching_operation_specifier of the dispatching operation set is checked using the Nonblocking and Global'Class aspect(s) applicable to the called dispatching operation; if there is a match, there is no checking against the Nonblocking or global aspects applicable at the point of call.
Is it clear that this only refers to the call itself and not to any checks associated with the evaluation of the parameters? (No.) In particular, the parameters are still considered to be read/written, right? (Yes.)
(2) In 5.6.1(4/5), type Expr_Ptr is defined at 3.9.1(14), but the cross-reference is to 3.9. Should this be fixed? (Yes.)
(3) In 3.9.1(14), the type Expression is defined at 3.9(33), but the cross-reference is to 3.10. Should this be fixed? (Yes.)
(4) In 3.3.1(8.1-4/5), the list of bullets is ended with semicolons, with a single "or" at the end of 3.3.1(8.3/5). However, similar nearby lists (in particular, 3.3(23-23.10/3)) have "or"s at the end of each bullet. Should we be consistent with those examples? (Yes.)
(5) In D(1), the reference to the Systems Programming Annex is not in the usual form. Should this be changed? (Yes.)
(6) The fourth sentence of D.1(15) is confusing. Should we replace "... generally reflects its base priority as well as any priority it inherits" with: "...may supersede its base priority with an inherited priority (see D (20/2))" (Not exactly.)
(7) D.1(23) is confusing now that it follows the newly added D.1(22.1/5). Should it be clarified? (Yes.)
(8) D.3(13.1/5) says: "If the ceiling priority of a protected object designates one with EDF_Within_Priorities". It's weird to say that a policy is "designated". Should this be reworded? (Yes.)
(9) D.3(13.4/5) is awkward. Should this be reworded? (Yes.)
(10) D.3(15-18/5) should have commas separating the parts. Right? (Yes.)
!recommendation
(1) Merge this entire rule with H.7.1(14/5), as there is no actual Legality Rule in it anyway, and clarify that we're only talking about the checks associated with the call and not any other checks that are nearby (including those associated with the parameters).
(2) & (3) Change the cross-references as suggested.
(4) Add "or" to the end of 3.3.1(8.2/5).
(5) In D(1), replace "the Systems Programming Annex" with "Annex C, "Systems Programming Annex"".
(6) Modify the fourth sentence of D.1(15) (see Wording.)
(7) Clarify that this bullet applies while a task is executing a protected action.
(8) Replace D.3(13.1/5) with:
If the task dispatching policy specified for the ceiling priority of a protected object is EDF_Within_Priorities, the following additional rules apply:
(9) Replace D.3(13.4/5) with:
While a task executes a protected action on a protected object P, it inherits the relative deadline of P. In this case, let DF be 'now' ('now' is obtained via a call on Ada.Real_Time.Clock at the start of the action) plus the deadline floor of P. If the active deadline of the task is later than DF, its active deadline is reduced to DF Redundant[; the active deadline is unchanged otherwise].
Note that here we are specifying when 'now' is obtained, it's important to say something so that it doesn't appear that it is obtained continuously "while a task executes a protected action". (That's a flaw of the original wording, too.)
(10) Add commas as needed. Note that the paragraph numbers were wrong in Draft 26 for these paragraphs (they're inserted paragraphs, renumbered in Ada 202x because of the previous insertion).
!wording
Modify 3.3.1(8.2/5):
* it has an access discriminant value constrained by a per-object expression; {or}
Modify 3.9.1(14):
type Expr_Ptr is access all Expression'Class; -- see 3.{9}[10]
Modify 5.6.1(4/5):
procedure Traverse (T : Expr_Ptr) is -- see 3.9{.1}
Modify D(1):
This Annex specifies additional characteristics of Ada implementations intended for real-time systems software. To conform to this Annex, an implementation shall also conform to [the Systems Programming Annex]{Annex C, "Systems Programming"}.
Modify D.1(15):
A task priority is an integer value that indicates a degree of urgency and is the basis for resolving competing demands of tasks for resources. Unless otherwise specified, whenever tasks compete for processors or other implementation-defined resources, the resources are allocated to the task with the highest priority value. The base priority of a task is the priority with which it was created, or to which it was later set by Dynamic_Priorities.Set_Priority (see D.5). At all times, a task also has an active priority, which generally [reflects]{is} its base priority {unless}[as well as any priority] it inherits {some priority} from other sources. Priority inheritance is the process by which the priority of a task or other entity ([e.g.]{for example,} a protected object; see D.3) is used in the evaluation of another task's active priority.
Modify D.1(23):
[During]{While a task executes} a protected action on a protected object, {the}[a]task inherits the ceiling priority of the protected object (see 9.5 and D.3).
Modify D.3(13.1/5):
If the {task dispatching policy specified for the} ceiling priority of a protected object [designates one with]{is} EDF_Within_Priorities, the following additional rules apply:
Replace D.3(13.4/5):
While a task executes a protected action, it inherits the relative deadline of the corresponding protected object so that its active deadline is reduced to (if it is currently greater than) 'now' plus the deadline floor of the corresponding protected object; 'now' is obtained via a call on Ada.Real_Time.Clock.
with:
While a task executes a protected action on a protected object P, it inherits the relative deadline of P. In this case, let DF be 'now' ('now' is obtained via a call on Ada.Real_Time.Clock at the start of the action) plus the deadline floor of P. If the active deadline of the task is later than DF, its active deadline is reduced to DF Redundant[; the active deadline is unchanged otherwise].
Modify D.3(13.7/5) [incorrectly numbered D.3(15) in Draft 26]:
* at any time prior to executing the entry body{,} Program_Error is raised
in the calling task;
Modify D.3(13.8/5) [incorrectly numbered D.3(16) in Draft 26]:
* when the entry is open{,} the entry body is executed at the ceiling priority
of the protected object;
Modify D.3(13.9/5) [incorrectly numbered D.3(17) in Draft 26]:
* when the entry is open{,} the entry body is executed at the ceiling priority
of the protected object and then Program_Error is raised in the calling task; or
Modify D.3(13.10/5) [incorrectly numbered D.3(18) in Draft 26]:
* when the entry is open{,} the entry body is executed at the ceiling priority
of the protected object that was in effect when the entry call was queued.
Modify H.7.1(14/5):
The dispatching operation set is identified by a set of dispatching_operation_specifiers. It indicates that the Nonblocking and global effects of dispatching calls that match one of the specifiers need not be accounted for by the Nonblocking or global aspect, but are instead to be accounted for by the invoker of the operation. A dispatching call matches a dispatching_operation_specifier if the name or prefix of the call statically denotes the same operation(s) as that of the dispatching_operation_specifier, and at least one of the objects controlling the call is denoted by, or designated by, a name that statically names the same object as that denoted by the object_name of the dispatching_operation_specifier. {
}In the absence of any dispatching_operation_specifiers{, or if none of them match a dispatching call C within an operation P}, Nonblocking and global aspects checks are performed at the point of [a dispatching]{the} call {C} within [the operation]{P} using the Nonblocking and Global'Class aspects that apply to the [named] dispatching operation {named in call C}. {If there is a match, any global access or potential blocking within the subprogram body invoked by the call C is ignored at the point of call within P. Instead, when the operation P itself is invoked, Nonblocking and global aspect checks are performed presuming each named dispatching operation is called at least once (with the named object controlling the call), but similarly ignoring those dispatching calls that would match a dispatching_operation_specifier applicable at the point of invocation of P.}
Delete H.7.1(17/5) and H.7.1(18/5) [these are moved above].
!discussion
(See !recommendation.)
!corrigendum 3.3.1(8.1/2)
Replace the paragraph:
A component of an object is said to require late initialization if it has an access discriminant value constrained by a per-object expression, or if it has an initialization expression that includes a name denoting the current instance of the type or denoting an access discriminant.
by:
A component of an object is said to require late initialization if:
!corrigendum 3.9.1(14)
Replace the paragraph:
type Expr_Ptr is access all Expression'Class; -- see 3.10
by:
type Expr_Ptr is access all Expression'Class; -- see 3.9
!corrigendum 5.6.1(0)
Insert new clause:
See the conflict file for the changes.
!corrigendum D(1)
Replace the paragraph:
This Annex specifies additional characteristics of Ada implementations intended for real-time systems software. To conform to this Annex, an implementation shall also conform to the Systems Programming Annex.
by:
This Annex specifies additional characteristics of Ada implementations intended for real-time systems software. To conform to this Annex, an implementation shall also conform to Annex C, "Systems Programming".
!corrigendum D.1(15)
Replace the paragraph:
A task priority is an integer value that indicates a degree of urgency and is the basis for resolving competing demands of tasks for resources. Unless otherwise specified, whenever tasks compete for processors or other implementation-defined resources, the resources are allocated to the task with the highest priority value. The base priority of a task is the priority with which it was created, or to which it was later set by Dynamic_Priorities.Set_Priority (see D.5). At all times, a task also has an active priority, which generally reflects its base priority as well as any priority it inherits from other sources. Priority inheritance is the process by which the priority of a task or other entity (e.g. a protected object; see D.3) is used in the evaluation of another task's active priority.
by:
A task priority is an integer value that indicates a degree of urgency and is the basis for resolving competing demands of tasks for resources. Unless otherwise specified, whenever tasks compete for processors or other implementation-defined resources, the resources are allocated to the task with the highest priority value. The base priority of a task is the priority with which it was created, or to which it was later set by Dynamic_Priorities.Set_Priority (see D.5). At all times, a task also has an active priority, which generally is its base priority unless it inherits a priority from other sources. Priority inheritance is the process by which the priority of a task or other entity (for example, a protected object; see D.3) is used in the evaluation of another task's active priority.
!corrigendum D.1(23)
Replace the paragraph:
by:
!corrigendum D.3(13)
Insert after the paragraph:
the new paragraphs:
If the task dispatching policy specified for the ceiling priority of a protected object is EDF_Within_Priorities, the following additional rules apply:
!corrigendum D.3(13.2/2)
Replace the paragraph:
by:
!corrigendum D.3(13.3/2)
Replace the paragraph:
by:
!corrigendum D.3(13.4/2)
Replace the paragraph:
by:
!corrigendum D.3(13.5/2)
Replace the paragraph:
by:
!ASIS
No ASIS effect.
!ACATS test
No ACATS tests should be needed, none of these changes change any semantics.
!appendix

From: Claire Dross
Sent: Friday, September 18, 2020  9:54 AM

[From her RM review.]

Annex H-7-1

17/5 Within an operation to which a Dispatching aspect applies, any dispatching 
call that does not match any dispatching_operation_specifier of the dispatching 
operation set is checked using the Nonblocking and Global'Class aspect(s) 
applicable to the called dispatching operation; if there is a match, there is 
no checking against the Nonblocking or global aspects applicable at the point 
of call.

>> Is it clear that parameters are still considered to be read/written? should 
we add a comment?

****************************************************************

From: Tucker Taft
Sent: Friday, September 18, 2020  10:39 AM

> Annex H-7-1
> 
> 17/5 Within an operation to which a Dispatching aspect applies, any 
> dispatching call that does not match any 
> dispatching_operation_specifier of the dispatching operation set is 
> checked using the Nonblocking and Global'Class aspect(s) applicable to 
> the called dispatching operation; if there is a match, there is no 
> checking against the Nonblocking or global aspects applicable at the 
> point of call.
> 
>>> Is it clear that parameters are still considered to be read/written? 
>>> should we add a comment?

Perhaps an AARM note with an example where the actual parameter is a global, 
indicating it should be treated as a read and/or write of that global.  
Normative wording could perhaps be clarified by saying "checking {of these 
aspects} against the ...".  Hence:

"Within an operation to which a Dispatching aspect applies, any dispatching 
call that does not match any dispatching_operation_specifier of the 
dispatching operation set is checked using the Nonblocking and Global'Class 
aspect(s) applicable to the called dispatching operation; if there is a match,
there is no checking of these aspects against the Nonblocking or global 
aspects applicable at the point of call."

****************************************************************

Editor's note: A summary of private mail between me and Tucker Taft.

Randy:

Humm. I think this makes it worse, because it's not at all clear what "these 
aspects" refer to. The noun here is "a Dispatching aspect"; I know you're not
talking about that.

I suspect some the confusion here is that the two parts here seem to be 
talking about slightly different parts of the process; the first talks 
about "checking" using the N and G aspects of the called operation, but 
doesn't say anything about what that entails, whereas the second talks 
about "not checking" (unidentified aspects) against some specific aspects 
at the point of the call.

It would be better if the two halves were truly equivalent, talking about 
exactly the same thing. I realize that's not easy to do. The overly long 
version would be something like:

"Within an operation to which a Dispatching aspect applies, any dispatching 
call that does not match any dispatching_operation_specifier of the dispatching
operation set is checked {against the Nonblocking or global aspects applicable 
at the point of call} using the Nonblocking and Global'Class aspect(s) 
applicable to the called dispatching operation; if there is a match, there 
is no checking {of the Nonblocking and Global'Class aspect(s) applicable to 
the called dispatching operation} against the Nonblocking or global aspects 
applicable at the point of call."

It might be best to mention that we're talking about the "usual" check in the 
first case (which of course makes it longer still):

"Within an operation to which a Dispatching aspect applies, any dispatching 
call that does not match any dispatching_operation_specifier of the 
dispatching operation set is checked {in the normal way against the 
Nonblocking or global aspects applicable at the point of call} using the 
Nonblocking and Global'Class aspect(s) applicable to the called dispatching
operation; if there is a match, there is no checking {of the Nonblocking and
Global'Class aspect(s) applicable to the called dispatching operation} against 
the Nonblocking or global aspects applicable at the point of call."

I suspect this can be refactored to simplify and clarify it. Perhaps:

"Within an operation to which a Dispatching aspect applies, the manner in 
which the Nonblocking and Global'Class aspect(s) of a dispatching call are 
checked against the Nonblocking or global aspects applicable at the point of 
call depends upon the Dispatching aspect(s) that apply. In particular, for any 
dispatching call that does not match any dispatching_operation_specifier of 
the dispatching operation set the aspects are checked in the normal way; if 
there is a match, there is no checking of those aspects."

Maybe "in the normal way" would be better phrased as "as usual"? Or more 
pedantically "as described elsewhere in this Standard"?

Maybe there even a better way to organize this wording?

Tucker:

> Humm. I think this makes it worse, because it's not at all clear what 
> "these aspects" refer to. The noun here is "a Dispatching aspect"; I 
> know you're not talking about that.

To me it seems pretty clear what "these aspects" refers to, since it is plural 
while "dispatching aspect" is singular.  But perhaps we can avoid any hint of 
ambiguity.

...
> Maybe there even a better way to organize this wording?

I don't think "normally" or "usually" work very well here, so I think we 
should be a bit more pedantic.

In fact, I would suggest we merge this legality-rule paragraph's content 
(and the one following) into the Static Semantics section, as they seem 
closely related to a Static Semantics paragraph (14/5), and there is no 
"shall" or "shall not" in these paragraphs anyway.

Hence, I would suggest the following:

Modify H.7.1(14/5):

The dispatching operation set is identified by a set of 
dispatching_operation_specifiers. It indicates that the Nonblocking and 
global effects of dispatching calls that match one of the specifiers need 
not be accounted for by the Nonblocking or global aspect, but are instead 
to be accounted for by the invoker of the operation. A dispatching call 
matches a dispatching_operation_specifier if the name or prefix of the call 
statically denotes the same operation(s) as that of the 
dispatching_operation_specifier, and at least one of the objects controlling 
the call is denoted by, or designated by, a name that statically names the 
same object as that denoted by the object_name of the 
dispatching_operation_specifier. {

}In the absence of any dispatching_operation_specifiers{, or if none of them 
match a dispatching call C within an operation P}, Nonblocking and global 
aspects checks are performed at the point of [a dispatching]{the} call {C} 
within [the operation]{P} using the Nonblocking and Global'Class aspects that
apply to the [named] dispatching operation {named in call C}. {If there is a 
match, any global access or potential blocking within the subprogram body 
invoked by the call C is ignored at the point of call within P. Instead, 
when the operation P itself is invoked, Nonblocking and global aspect checks 
are performed presuming each named dispatching operation is called at least 
once (with the named object controlling the call), but similarly ignoring 
those dispatching calls that would match a dispatching_operation_specifier 
applicable at the point of invocation of P.}

-------

Then we can delete H.7.1(17/5 and 18/5).

****************************************************************

From: Jeff Cousins
Sent: Wednesday, October 28, 2020  4:40 AM

The example in AI12-0119, inserted as 5.6.1 (4/5), says:

procedure Traverse
   (T : Expr_Ptr) -- see 3.9
is begin
   if T /= null
   and then T.all in Binary_Operation'Class -- see 3.9.1

 Expr_Ptr is actually defined in 3.9.1 too, at 3.9.1 (14):

14
type Expr_Ptr is access all Expression'Class;
                               -- see 3.10

This in turn refers to 3.10 for a definition of Expression, but it is
actually defined in 3.9, at 3.9 (33):

33
type Expression is tagged null record;
  -- Components will be added by each extension

****************************************************************

[From the AARM Review of Gary Dismukes, October 2020]

3.3.1 (Object Declarations)
---------------------------

Add "or" at end of initial bullet item:

8.2/5
{AI12-0192-1} it has an access discriminant value constrained by a per-object 
expression; {or}

****************************************************************

[From the AARM Review of Tullio Vardanega, October 2020]

D (1): ... shall also conform to the Systems Programming Annex 
should rather say: 
... to Annex C, “Systems Programming”.


D (15): ... generally reflects its base priority as well as any priority it 
inherits
should rather say: 
may supersede its base priority with an inherited priority (see D (20/2))

Editor's reply:

  You mean D.1(15) here. We can't have cross-references to specific paragraphs 
  (there are no paragraph numbers in the ISO version of the Standard), and it 
  doesn't make sense to cross-reference within the same clause. So we can't 
  have a cross-reference here.

  This whole subclause is introductory material, I'm not sure how specific we 
  want to get with this wording. In particular, this subclause applies to all 
  dispatching policies (including implementation-defined ones). So we have to 
  be careful to not say anything that might not apply to some policy.

  Anyway, I don't think this rewording works very well with the first part of 
  the sentence; the original version is defining what the active priority of 
  a task is "at all times":
   
     At all times, a task also has an active priority, which generally reflects 
     its base priority as well as any priority it inherits from other sources. 

  while your version doesn't indicate that the active priority is usually the 
  base priority unless something is inherited. Perhaps we can split the 
  difference:

     At all times, a task also has an active priority, which generally is its 
     base priority unless it inherits some priority from other sources. 

  I left the "generally" to leave an escape hatch for some unusual dispatching 
  policy. I'm unsure if this is really an improvement.

D (23): During a protected action on a protected object, a task inherits the 
ceiling priority of the protected object (see 9.5 and D.3).
In light of (22.1/5) that precedes it, should rather say: 
While a task executes a protected action, it inherits the ceiling priority of 
the corresponding protected object (see 9.5 and D.3).

Editor's reply:
  (Also D.1, not D.)

  "it" in the revised wording is a bit ambigiuous (it could be referring to 
  the task or the protected action). I'd suggest saying "the task" instead. 
  It's also weird to talk about "corresponding" protected objects. I think the
  original construction is better for that. So we get:

     While a task executes a protected action on a protected object, the task 
     inherits the ceiling priority of the protected object (see 9.5 and D.3).

D.3 (13.1/5) 
I do not understand “If the ceiling priority of a protected object designates 
one with EDF_Within_Priorities”.
Perhaps it should read: 
If EDF_Within_Priorities applies to the ceiling priority of a protected object, 

Editor's reply:
  Agreed, "designates" is weird. But "applies" isn't much better. A priority has 
  a specified task dispatching policy, so I think we want to say that.

  Perhaps:

   "If the task dispatching policy specified for the ceiling priority of a 
    protected object is EDF_Within_Priorities ..."

D.3 (13.4/5): While a task executes a protected action, it inherits the 
relative deadline of the corresponding protected object so that its active
deadline is reduced to (if it is currently greater than) 'now' plus the 
deadline floor of the corresponding protected object
	Reads awkward. 
	Perhaps it should read: 
While a task executes a protected action, it inherits the relative deadline 
of the corresponding protected object so that its active deadline is reduced
to 'now' plus the deadline floor of the corresponding protected object. No
such reduction occurs if the task’s active deadline is already lower than that.

Editor's reply:
  I agree this is awkward. But I don't think your version is an improvement, 
  as I have no clue what "that" is (besides intuition, of course). And it 
  doesn't make sense to talk about a "reduction" to a larger value, even if 
  we're not doing it. (And the "corresponding protected object" has shown up
  again - twice!) Probably this needs to be broken up into multiple sentences.
  Perhaps:

    While a task executes a protected action on a protected object P, it 
    inherits the relative deadline of P. In this case, let DF be 'now' plus
    the deadline floor of P. If the active deadline of the task is later than
    DF, its active deadline is reduced to DF Redundant[; the active deadline 
    is unchanged otherwise].

  Side issue: This bullet seems wrong to me. We want to do this only once, 
  when the action starts, right? The wording says that it occurs "while a task
  executes a protected action", which seems to imply that the active priority 
  is continuously being updated. But that doesn't make any sense, both because
  of the implementation complications, and because in that case the inherited 
  deadline would never trigger (it would continuously be updated to the 
  relative deadline of the PO).

  Probably the best idea is to specify when 'now' is obtained, so it is clear 
  that it isn't continuous somehow. Maybe adding "at the start of the action" 
  would be enough?

****************************************************************

Questions? Ask the ACAA Technical Agent