Version 1.4 of ai12s/ai12-0031-1.txt
!standard E.2.3(19/3) 12-11-17 AI12-0031-1/02
!class binding interpretation 12-11-17
!status work item 12-06-06
!status received 12-05-17
!priority Low
!difficulty Medium
!subject All_Calls_Remote and indirect calls
!summary
All_Calls_Remote only applies to direct calls.
!question
Does E.2.3(19/3) apply to indirect calls (that is those through
access-to-subprogram values)? (No.)
There are unnecessary complications if the clause applies to calls through
access-to-subprogram objects.
For example, if the program calls through a remote-access-to-subprogram
object, the access object will probably contain a partition_ID, and it
makes sense for the caller to check to see if the partition_ID refers to
the current partition and make a local call if so. But if the rules
require that it be a PCS call if the subprogram is in an
All_Calls_Remote package, the code would have to somehow determine
whether the subprogram address were in such a package.
Similarly, in the case of a normal access-to-subprogram object: the
access object is probably just the address of a subroutine, and it would
be the same subroutine that would be called for a direct call, which,
for a remote subprogram in an All_Calls_Remote package, would be the
address of a subroutine that uses the PCS to call the target routine. If
such an access-to-subprogram object were then passed to a routine in a
child package of the RCI unit, and the second sentence of E.2.3(19)
applied to indirect calls, the child package code would have to somehow
check the address in the access-to-subprogram object to see if it refers
to a remote subprogram in the parent unit, so that it could make a local
call instead of going through the PCS.
!recommendation
The wording is changed so that the All_Calls_Remote aspect only applies
to direct calls to an RCI unit package. Indirect calls are always
considered as being outside of the declarative region and it is up to
the implementation to decide whether such calls to the same partition
are routed through the PCS.
!wording
Modify AARM E.2.3(16.a/3):
Aspect Description for All_Calls_Remote: All {direct} remote procedure
calls {from outside the declarative region of the RCI unit} should use
the Partition Communication Subsystem[, even if they are local].
Modify E.2.3(19/3):
If aspect All_Calls_Remote is True for a given RCI library unit, then
the implementation shall route any {direct} call to a subprogram of
the RCI unit from outside the declarative region of the unit through
the Partition Communication Subsystem (PCS); see E.5. {Direct calls}
[Calls] to such subprograms from within the declarative region of the
unit are defined to be local and shall not go through the PCS.
Modify AARM E.2.3(19.a/3):
When this aspect is False (or not used), it is presumed that most
implementations will {not involve the PCS}[make direct calls] if the
call originates in the same partition as that of the RCI unit. When
this aspect is True, all {direct} calls from outside the subsystem
rooted at the RCI unit package are treated like calls from outside the
partition, ensuring that the PCS is involved in all such calls (for
debugging, redundancy, etc.).
Add to AARM E.2.3(19.b):
This aspect does not apply to indirect calls because the overhead
in determining whether an actual subprogram parameter is declared in
an All_Calls_Remote RCI unit or within the declarative region of
such a unit was deemed not to be worthwhile.
!discussion
Consider:
package Server_RCI_Package is
pragma Remote_Call_Interface;
type Callback is access procedure;
procedure P (Call : Callback);
end Server_RCI_Package;
package body Server_RCI_Package is
procedure P (Call : Callback) is
begin
Call.all;
--
end P;
end Server_RCI_Package;
package Normal_RCI_Package is
pragma Remote_Call_Interface;
procedure Biff;
end Normal_RCI_Package;
package body Normal_RCI_Package is
procedure Biff is
begin
--
...
end Biff;
end Normal_RCI_Package;
package All_Calls_Remote_Package is
pragma Remote_Call_Interface;
pragma All_Calls_Remote;
procedure Bam;
end All_Calls_Remote_Package;
package body All_Calls_Remote_Package is
procedure Bam is
begin
... --
end Bam;
end All_Calls_Remote_Package;
package All_Calls_Remote_Package.Child is
pragma Remote_Call_Interface;
type Callback is access procedure;
procedure Pow (Cb : Callback);
end All_Calls_Remote_Package.Child;
package body All_Calls_Remote.Child is
procedure Pow (Cb : Callback) is
begin
Cb;
--
--
end Pow;
end All_Calls_Remote_Package.Child;
with Server_RCI_Package;
with All_Calls_Remote_Package.Child;
with Normal_RCI_Package;
procedure Distributed is
begin
--
Server_RCI_Package.P
(Call => All_Calls_Remote_Package.Bam'access);
--
Server_RCI_Package.P
(Call => Normal_RCI_Package.Biff'access);
--
All_Calls_Remote_Package.Child.Pow
(Cb => All_Calls_Remote_Package.Bam'access);
--
--
All_Calls_Remote_Package.Child.Pow
(Cb => Normal_RCI_Package.Biff'access);
end Distributed;
According to E.2.1 (19/3), the call at A => should be routed through
the PCS, since the Bam subprogram is declared in an All_Calls_Remote
package. However the call at B => presumably wouldn't go through the PCS
if the Normal_RCI_Package and the Server_RCI_Package belonged to the
same partition.
In order for the body of Server_RCI.P to make this distinction,
it would require a mechanism to determine whether the actual parameter
was declared in an All_Call_Remotes RCI unit.
Conversely, according to the latter part of E.2.1 (19/3), the call at
C => should not be routed through the PCS, since the call is being made
within the declarative region of the All_Calls_Remote RCI unit. However,
the call at D=> would go through the PCS if Normal_RCI_Package belonged
to a different partition than All_Calls_Remote_Package.
The body of All_Calls_Remote_Package.Child.Pow would need to have a
mechanism to determine whether the actual parameter is declared within
the same declarative region, and if so, have a means to convert the
remote subprogram address to the local direct subprogram address.
Addressing these complications would involve introducing overhead for
the calls and are not worth solving for a pragma that may be typically
used only for debugging purposes.
Instead, these complications can be avoided if the All_Calls_Remote
pragma is clarified to only apply to direct calls to RCI units. It is
up to the implementation to decide whether indirect calls to an RCI unit
through a remote access-to-subprogram object in the same partition needs
to be routed through the PCS.
It was considered whether the pragma should be dropped from the standard
altogether, since All_Calls_Remote is not entirely true if certain calls
can be local. It was decided that it was worthwhile keeping the pragma
because it is useful for debugging and testing a PCS, and because
calls to an RCI unit are more typically direct calls.
!ACATS test
** TBD.
!appendix
From: Adam Beneschan
Sent: Thursday, May 17, 2012 3:12 PM
!topic Clarification on E.2.3(19)
!reference E.2.3(19)
!from Adam Beneschan 12-05-17
!discussion
Regarding this implementation requirement:
If aspect All_Calls_Remote is True for a given RCI library unit,
then the implementation shall route any call to a subprogram of
the RCI unit from outside the declarative region of the unit
through the Partition Communication Subsystem (PCS); see
E.5. Calls to such subprograms from within the declarative region
of the unit are defined to be local and shall not go through the
PCS.
are the "calls" mentioned here intended to refer only to direct calls, or also
to indirect ones? It seems like there are unnecessary complications if the
clause is supposed to apply to calls through access-to-subprogram objects. For
example, if the program calls through a remote-access-to-subprogram object, the
access object will probably contain a partition_ID, and it makes sense for the
caller to check to see if the partition_ID refers to the current partition and
make a local call if so. But if the rules require that it be a PCS call if the
subprogram is in an All_Calls_Remote package, the code would have to somehow
determine whether the subprogram address were in such a package.
Or in the case of a normal access-to-subprogram object: the access object is
probably just the address of a subroutine, and it would be the same subroutine
that would be called for a direct call, which, for a remote subprogram in an
All_Calls_Remote package, would be the address of a subroutine that uses the PCS
to call the target routine. If such an access-to-subprogram object were then
passed to a routine in a child package of the RCI unit, and the second sentence
of E.2.3(19) applied to indirect calls, the child package code would have to
somehow check the address in the access-to-subprogram object to see if it refers
to a remote subprogram in the parent unit, so that it could make a local call
instead of going through the PCS.
****************************************************************
From: Brad Moore
Sent: Sunday, June 16, 2013 1:40 AM
The discussion of this AI yesterday arrived at this being a no action AI, and
the answer to the question being asked was changed to indicate that
All_Calls_Remote also applied to indirect calls from outside the declarative
region of the RCI package. The reasoning was that it would not be difficult to
add a bit of information to the fat pointer associated with a
remote-access-to-subprogram object to indicated whether the call came from
an All_Calls_Remote package.
That is likely true, but I think the other case described in the AI is still a
problem, and is the main issue that needs to be solved. This is the case of a
normal access-to-subprogram object that happens to denote a subprogram in an
All_Calls_Remote package, when the call is being made from within the
declarative region of the RCI subprogram. This normal access-to-subprogram
object is likely not a fat pointer, and ordinarily would just invoke the
denoted All_Calls_Remote subprogram through the PCS. E.2.3(19/3) currently
says that this needs to be a local call though, yet it would likely be
difficult for the implementation to determine that the call is being made
from within the same declarative region.
The examples I had in the AI discussion unfortunately did not actually
capture this case.
Here I think is a more specific example.
package RCI_Package is
pragma Remote_Call_Interface;
pragma All_Calls_Remote;
procedure P;
end RCI_Package;
with Normal_Package;
package body RCI_Package is
procedure Foo (Cb : Normal_Package.Callback) is
begin
Cb.all; -- Supposed to be local call to P from
-- within declarative region.
-- How can we determine this normal access-to-subprogram
-- denotes an All_Calls_Remote subprogram from within
-- the same declarative region?
end Foo;
procedure X is -- this gets called somehow
begin
Normal_Package.Doit (Foo'Access);
end X;
procedure P is
begin
...
end P;
end RCI_Package.Child;
package Normal_Package is
type Callback is access procedure;
procedure Doit (Cb : Callback);
end Normal_Package;
with RCI_Package;
package body Normal_Package is
procedure Doit (Cb : Callback) is
begin
Cb.all (RCI_Package.P'Access);
-- Normal access-to-subprogram object, which invokes
-- an All_Calls_Remote subprogram though PCS
end Doit;
end Normal_Package;
Based on this, I think perhaps that the AI as it was originally written up, is
closer to what we want.
****************************************************************
Questions? Ask the ACAA Technical Agent