[Ada] Make Ada.Task_Initialization compatible with No_Elaboration_Code_All

Message ID 20210922151528.GA1907511@adacore.com
State Committed
Commit d232417a8832c480abeb1c28abd66978b85e5081
Headers
Series [Ada] Make Ada.Task_Initialization compatible with No_Elaboration_Code_All |

Commit Message

Pierre-Marie de Rodat Sept. 22, 2021, 3:15 p.m. UTC
  So that this unit can be used and called even before elaboration has
started, to ensure very early registration via e.g. C code.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

	* libgnarl/a-tasini.ads, libgnarl/a-tasini.adb: Make compatible
	with No_Elaboration_Code_All.
	* libgnarl/s-taskin.ads, libgnarl/s-tassta.adb: Adjust
	accordingly.
  

Patch

diff --git a/gcc/ada/libgnarl/a-tasini.adb b/gcc/ada/libgnarl/a-tasini.adb
--- a/gcc/ada/libgnarl/a-tasini.adb
+++ b/gcc/ada/libgnarl/a-tasini.adb
@@ -26,13 +26,13 @@ 
 --                                                                          --
 ------------------------------------------------------------------------------
 
-with Ada.Unchecked_Conversion;
-with System.Tasking;
-
 package body Ada.Task_Initialization is
 
-   function To_STIH is new Ada.Unchecked_Conversion
-     (Initialization_Handler, System.Tasking.Initialization_Handler);
+   Global_Initialization_Handler : Initialization_Handler := null;
+   pragma Atomic (Global_Initialization_Handler);
+   pragma Export (Ada, Global_Initialization_Handler,
+                  "__gnat_global_initialization_handler");
+   --  Global handler called when each task initializes.
 
    --------------------------------
    -- Set_Initialization_Handler --
@@ -40,7 +40,7 @@  package body Ada.Task_Initialization is
 
    procedure Set_Initialization_Handler (Handler : Initialization_Handler) is
    begin
-      System.Tasking.Global_Initialization_Handler := To_STIH (Handler);
+      Global_Initialization_Handler := Handler;
    end Set_Initialization_Handler;
 
 end Ada.Task_Initialization;


diff --git a/gcc/ada/libgnarl/a-tasini.ads b/gcc/ada/libgnarl/a-tasini.ads
--- a/gcc/ada/libgnarl/a-tasini.ads
+++ b/gcc/ada/libgnarl/a-tasini.ads
@@ -30,7 +30,8 @@ 
 --  when tasks start.
 
 package Ada.Task_Initialization is
-   pragma Preelaborate (Task_Initialization);
+   pragma Preelaborate;
+   pragma No_Elaboration_Code_All;
 
    type Initialization_Handler is access procedure;
 


diff --git a/gcc/ada/libgnarl/s-taskin.ads b/gcc/ada/libgnarl/s-taskin.ads
--- a/gcc/ada/libgnarl/s-taskin.ads
+++ b/gcc/ada/libgnarl/s-taskin.ads
@@ -368,14 +368,6 @@  package System.Tasking is
    --  Used to represent protected procedures to be executed when task
    --  terminates.
 
-   type Initialization_Handler is access procedure;
-   pragma Favor_Top_Level (Initialization_Handler);
-   --  Use to represent procedures to be executed at task initialization.
-
-   Global_Initialization_Handler : Initialization_Handler := null;
-   pragma Atomic (Global_Initialization_Handler);
-   --  Global handler called when each task initializes.
-
    ------------------------------------
    -- Dispatching domain definitions --
    ------------------------------------


diff --git a/gcc/ada/libgnarl/s-tassta.adb b/gcc/ada/libgnarl/s-tassta.adb
--- a/gcc/ada/libgnarl/s-tassta.adb
+++ b/gcc/ada/libgnarl/s-tassta.adb
@@ -35,6 +35,7 @@  pragma Partition_Elaboration_Policy (Concurrent);
 
 with Ada.Exceptions;
 with Ada.Unchecked_Deallocation;
+with Ada.Task_Initialization;
 
 with System.Interrupt_Management;
 with System.Tasking.Debug;
@@ -1177,6 +1178,14 @@  package body System.Tasking.Stages is
          Debug.Signal_Debug_Event (Debug.Debug_Event_Run, Self_ID);
       end if;
 
+      declare
+         use Ada.Task_Initialization;
+
+         Global_Initialization_Handler : Initialization_Handler;
+         pragma Atomic (Global_Initialization_Handler);
+         pragma Import (Ada, Global_Initialization_Handler,
+                        "__gnat_global_initialization_handler");
+
       begin
          --  We are separating the following portion of the code in order to
          --  place the exception handlers in a different block. In this way,