slide: 1 the implementation of ada 2005 synchronized interfaces in the gnat compiler javier miranda...
TRANSCRIPT
Slide: 1
The Implementation of Ada 2005 Synchronized Interfaces in the GNAT Compiler
Javier MirandaHristian KirtchevEdmond Schonberg
Presentation cover page EU
www.adacore.com
Slide: 2
Interfaces Types
• Interfaces in Ada 2005
• Implementation of regular interfaces
• Limited, Synchronized, Protected, and Task interfaces in Ada 2005
• Basic implementation model: Corresponding records
• Dispatching calls in selective waits
• Status
Slide: 3
Interface Types in Ada 2005
type Root is tagged record ... ; . . .
type DT_1 is new Root and I1 and I2 with record . . . ; -- Must provide the implementation of P and R
type DT_2 is new DT_1 with record . . . ; -- Inherits all the primitives and interfaces of the ancestor
type I1 is interface;function P (X : I1) return Natural is abstract;
type I2 is interface and I1; procedure Q (X : I2) is null; procedure R (X : I2) is abstract;
Slide: 4
procedure Dispatch_I1_Call (Obj : I1'Class) isbegin -- Dispatch call to user -- defined subprogram . . := P (Obj);
-- Dispatch call to predefined -- stream operation I1'Write (Stream, Obj);end Dispatch_I1_Call;
procedure Dispatch_Call (Obj : Root'Class) isbegin -- Membership test if Obj in I2'Class then R (I2'Class (Obj));
end if;end Dispatch_Call;
type I1 is interface;function P (X : I1) return Natural is abstract;
type I2 is interface and I1; procedure Q (X : I2) is null; procedure R (X : I2) is abstract;
Interface Types in Ada 2005
Slide: 5
GNAT Implementation
• Main features:– Constant-time dispatching calls through interfaces– Compatible with the C++ ABI Layout
http://www.codesourcery.com/cxx-abi
• J.Miranda, E.Schonberg, G.Dismukes. The Implementation of Ada 2005 Interfaces Types in the
GNAT Compiler. AdaEurope’2005, York. Lecture Notes in Computer Science. Eds: T.Vardanega,
A.Wellings. Vol. 3555, pages 208-219. June, 2005. Springer-Verlag.
ISSN 0302-9743 ISBN 3-540-26286-5
Slide: 6
GNAT Object Layout: Example
Slide: 7
Primary and secondary dispatch tables
Slide: 8
C++ structure with abstract classes
Slide: 9
Interface Dispatching Call
Slide: 10
procedure P (Obj : DT; << formals >>) is ... . . .end P;
procedure I1_P_Thunk (Obj_Addr : Address; << formals>>) is M : constant := DT.I1'Position; Obj_Base : constant := Obj_Addr – Storage_Offset (M);begin P (Obj_Base, << formals >>); -- In practice not a call but a jumpend I1_P_Thunk;
Thunk Code
Slide: 11
Interface categories
• Regular interfaces– Implemented by tagged record types
• Task interfaces– Implemented by task types
• Protected interfaces– Implemented by protected types
• Synchronized interfaces– Implemented by tasks or protected types
• Limited interfaces– Implemented by record, task, or protected types.
Slide: 12
Run-time representation of Synchronized types
• Similar discriminated records
• Protected types– Private data
– Lock structure
– Entry queues (discriminated component)
– Finalization queues• Task types
– Pointer to task control block
– Lock structures
– Size, priority
– Task info• Target-independent layout
• Simpler structure for Ravenscar profile
Slide: 13
Implementing a synchronized interface with a task
type I1 is limited interface; procedure P (Obj : in out I1) is abstract; procedure Q (Obj : in out I1) is null;
type I2 is synchronized interface and I1; procedure R (Obj : in out I2; Data : Integer) is abstract;
task type Tsk is new I2 with entry P; -- Implements P of I1 entry R (Data : Integer); -- Implements R of I2 end Tsk;
procedure Q (T : in out Tsk); -- Implements Q of I1
Slide: 14
Implementation steps• Make corresponding records tagged (they are already limited)
– Interface dispatching data structures are as for regular interfaces
– Conformance rules must handle first argument specially
• Create wrappers for entries and protected operations– Wrappers are primitive operations of the corresponding record
– Interface dispatching calls require one additional call
• For entries, wrapper contains an entry call
• For protected operations, wrapper contains a call to the protected operation– Protected operation locks object, calls unprotected version
– Unprotected subprog contains code of operation (direct use in internal calls)
• Dispatching calls on a synchronized interface handle tasks and protected types uniformly
Slide: 15
Interface dispatching in selective wait and ATC
type I1 is limited interface; procedure P (X in out I1) is abstract;
protected type Prot1 is I1 with… type Lim is new I1 with record … end record;
procedure Dispatch (X: in out I1’class) is begin select X.P; -- protected or regular operation? else delay 0.1; end select; end Dispatch;
Slide: 16
Need additional Run-Time operationsto determine kind of target
• Operations on all types that implement limited interfaces:– Get_Prim_Op_Kind
– Record, task, or protected type operation? Procedure or entry?
– Get_Entry_Index– If entry-call, position of entry queue in object– Could be combined with previous operation
– Get_Offset_Index– Index in primary table corresponding to interface operation in
secondary table
• Corresponding information must be added to the Run-Time Type-Specific Data
• Operations are not dispatching
Slide: 17
New Dispatching Operations
• Expansion of selective waits depends critically on whether trigger is task or protected operation: no possible factorization
• Primitive operations for selective waits– Dispatching_Timed_Select
– Dispatching_Conditional_Select
• Primitive operations for ATC– Dispatching_Asynchronous_Select
– Dispatching_Get_Prim_Op_Kind
• Primitive operations for task interfaces– Dispatching_Get_Task_Id (for task abortion and attributes ‘Callable and
‘Terminated)
Slide: 18
Dispatch Table Structure
type Lim_Iface is limited interface;procedure A (Obj : in out Lim_Iface) is abstract;
type Synch_Iface is synchronized interface;procedure B (Obj : in out Synch_Iface) is abstract;
protected type Prot_Typ is new Lim_Iface and Synch_Ifacewith procedure A; entry B;end Prot_Typ;
P : Prot_Typ;
Offset_To_TopOSD_Ptr : Predefined : thunks : tableThunk_A’address
Secondary DT
Offset_To_TopOSD_Ptr : Predefined : thunks : tableThunk_B’address
Secondary DT
_Tag_DT1_DT2…Queues
POffset_To_TopTSD_Ptr : Predefined : primitives : table A’address B’address
Primary DT
Inheritance depthAccess levelExpanded nameExternal tag. . . SSD_PtrAncestor tagsInterface tags
Type Specific Data
B’Pos in the Primary DT
Offset Specific Data
A Prot.Proc -B Prot.Entry 1
Select Specific Data
A’Pos in the Primary DT
Offset Specific Data
Slide: 19
with DT_Pkg; use DT_Pkg;
procedure Simple_Dispatching is procedure Dispatch_On_A (Obj : in out Lim_Iface’Class) is begin
end Dispatch_On_A;
P : Prot_Typ;
begin
end Simple_Dispatching;
Interface dispatching call
_Tag_DT1_DT2…Queues
POffset_To_TopTSD_Ptr : Predefined : primitives : tableA’addressB’address
Primary DT
Offset_To_TopOSD_Ptr : Predefined : thunks : tableThunk_A’address
Secondary DT
Offset_To_TopOSD_Ptr : Predefined : thunks : tableThunk_B’address
Secondary DT
Inheritance depthAccess levelExpanded nameExternal tag. . .SSD_PtrAncestor tagsInterface tags
Type Specific Data
B’Pos in the primary DT
Offset Specific Data
A Prot_Proc -B Prot_Entry 1
Select Specific Data
declare Temp_Tag : Tag := Tag (Obj); Temp_Addr : Address := Temp_Tag.all.prim_tbl (A’Pos); begin Temp_Addr (Obj); end;
Obj.A;
Dispatch_On_A (Lim_Iface (P._DT1)); Dispatch_On_A (P);
PP._DT1Obj
A’Pos in the primary DT
Offset Specific Data
Slide: 20
Dispatching in Selective waits
with Ada.Text_IO; use Ada.Text_IO;with DT_Pkg; use DT_Pkg;
procedure Select_Dispatching is procedure Select_On_B (Obj : in out Synch_Iface’Class) is begin declare B : Boolean := False; C : Prim_Op_Kind; D : Duration := To_Duration (1.0); K : Tagged_Kind := Get_Tagged_Kind (Tag (Obj)); M : Integer := 1; P : Parameters := (Param1 … ParamN); S : Integer; begin if K = TK_Limited_Tagged then Obj.B; else S := Get_Offset_Index ( Tag (Obj), DT_Position (B));
_DTS (Obj, S, P’Address, D, M, C, B);
if C = POK_Protected_Entry or else C = POK_Task_Entry then
with Ada.Text_IO; use Ada.Text_IO;with DT_Pkg; use DT_Pkg;
procedure Select_Dispatching is procedure Select_On_B (Obj : in out Synch_Iface’Class) is begin select Obj.B; or delay 1.0; Put_Line (“Delayed”); end select; end Select_On_A;
P : Prot_Typ;begin Select_On_B (P);end Select_Dispatching;
Param1 := P.Param1; . . . ParamN := P.ParamN; end if;
if B then if C = POK_Proc or else C = POK_Protected_Proc or else C = POK_Task_Proc then Obj.B; end if; <triggering-statements> else <delay-statements> end if; end if; end; end Select_On_B;
P : Prot_Typ;
procedure _DTS (T : Prot_TypV; S : Integer; P : System.Address; D : Duration; M : Integer;
C : out Prim_Op_Kind; B : out Boolean) is I : Integer; begin C := Get_Prim_Op_Kind (T._Tag, S); if C = POK_Proc or else C = POK_Protected_Proc or else C = POK_Task_Proc then B := True; return; end if; I := Get_Entry_Index (T._Tag, S);
-- If Prot_Typ is a task type, the -- following expansion has a call -- to Timed_Task_Entry_Call
System.Timed_Protected_Entry_Call (T._Object’Unchecked_Access, Protected_Entry_Index (I), P, D, M, B); end _DTS;
begin Select_On_B (Synch_Iface (P._DT2));end Select_Dispatching;
Slide: 21
with Ada.Text_IO; use Ada.Text_IO;with DT_Pkg; use DT_Pkg;
procedure Select_Dispatching is procedure Select_On_B (Obj : in out Synch_Iface’Class) is begin declare B : Boolean := False; C : Prim_Op_Kind; D : Duration := To_Duration (1.0); K : Tagged_Kind := Get_Tagged_Kind (Tag (Obj)); M : Integer := 1; P : Parameters := (Param1 … ParamN); S : Integer ; begin if K = TK_Limited_Tagged then Obj.B; else S := Get_Offset_Index ( Tag (Obj), DT_Position (B));
_DTS (Obj, S, P’Address, D, M, C, B);
Dispatching in Selective waits: Example
_Tag_DT1_DT2…Queues
Prot_TypVOffset_To_TopTSD_Ptr 01 Predefined : primitives : table16 A’address17 B’address
Primary DT
Offset_To_TopOSD_Ptr01 Predefined : thunks : table16 Thunk of A
Secondary DT
Offset_To_TopOSD_Ptr01 Predefined : thunks : table16 Thunk of B
Secondary DT
Inheritance depthAccess levelExpanded nameExternal tag. . .SSD_PtrAncestor tagsInterface tags
Type Specific Data
A’Pos = 16Offset Specific Data
B’Pos = 17Offset Specific Data
A Prot_Proc -B Prot_Entr 1
Select Specific Data is I : Integer; begin C := Get_Prim_Op_Kind (T._Tag, S);
if C = POK_Proc or else C = POK_Protected_Proc or else C = POK_Task_Proc then B := True; return; end if;
I := Get_Entry_Index (T._Tag, S);
System.Timed_Protected_Entry_Call (T._Object’Unchecked_Access, Protected_Entry_Index (I), P, D, M, B); end _DTS;
begin Select_On_B (Synch_Iface (P._DT2));end Select_Dispatching;
Slide: 22
GAP 2005 Release
Abstract Interface Types (including task, protected and synchronized interfaces) available in GAP-2005
All 2005 enhancements available to GNAT Pro users under -gnat05 switch.
Slide: 23
The Implementation of Ada 2005 synchronized Interfaces in the GNAT Compiler
Javier MirandaHristian KirtchevEdmond Schonberg
End of talk
Presentation cover page EU
www.adacore.com
Slide: 24
GNAT Implementation ApproachesPermutation Maps versus C++ Model
• Constant-time dispatching calls through interfaces• Compatibility with the C++ ABI Layout
Slide: 25
Basic dispatch table structure
Slide: 26
Primary dispatch table
Slide: 27