Version 1.6 of 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;
--
Modify 5.6.1(4/5):
procedure Traverse (T : Expr_Ptr) is --
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:
- it has an access discriminant value constrained by a per-object
expression; or
- it has an initialization expression that includes a name denoting an
access discriminant; or
- it has an initialization expression that includes a reference to the
current instance of the type either by name or implicitly as the
target object of a call.
!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:
- During a protected action on a protected object, a task inherits the
ceiling priority of the protected object (see 9.5 and D.3).
by:
- 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).
!corrigendum D.3(13)
Insert after the paragraph:
- When a task calls a protected operation, a check is made that its
active priority is not higher than the ceiling of the corresponding
protected object; Program_Error is raised if this check fails.
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:
- Every protected object has a relative deadline, which is
determined by a Relative_Deadline aspect as defined in D.2.6, or by
assignment to the Relative_Deadline attribute as described in D.5.2. The
relative deadline of a protected object represents a lower bound on the
relative deadline a task may have when it calls a protected operation of that
protected object.
- If aspect Relative_Deadline is not specified for a protected type
then the initial relative deadline of the corresponding protected object is
Ada.Real_Time.Time_Span_Zero.
- 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; the active
deadline is unchanged otherwise.
- When a task calls a protected operation, a check is made that its
active deadline minus its last release time is not less than the
relative deadline of the corresponding protected object; Program_Error
is raised if this check fails.
!corrigendum D.3(13.2/2)
Replace the paragraph:
- at any time prior to executing the entry body Program_Error is raised
in the calling task;
by:
- at any time prior to executing the entry body, Program_Error is raised
in the calling task;
!corrigendum D.3(13.3/2)
Replace the paragraph:
- when the entry is open the entry body is executed at the ceiling
priority of the protected object;
by:
- when the entry is open, the entry body is executed at the ceiling
priority of the protected object;
!corrigendum D.3(13.4/2)
Replace the paragraph:
- 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
by:
- 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
!corrigendum D.3(13.5/2)
Replace the paragraph:
- 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.
by:
- 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.
!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