File : s-tporft.adb


   1 ------------------------------------------------------------------------------
   2 --                                                                          --
   3 --                 GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS                 --
   4 --                                                                          --
   5 --         SYSTEM.TASK_PRIMITIVES.OPERATIONS.REGISTER_FOREIGN_THREAD        --
   6 --                                                                          --
   7 --                                B o d y                                   --
   8 --                                                                          --
   9 --          Copyright (C) 2002-2014, Free Software Foundation, Inc.         --
  10 --                                                                          --
  11 -- GNARL is free software; you can  redistribute it  and/or modify it under --
  12 -- terms of the  GNU General Public License as published  by the Free Soft- --
  13 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
  14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  16 -- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
  17 --                                                                          --
  18 --                                                                          --
  19 --                                                                          --
  20 --                                                                          --
  21 --                                                                          --
  22 -- You should have received a copy of the GNU General Public License and    --
  23 -- a copy of the GCC Runtime Library Exception along with this program;     --
  24 -- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
  25 -- <http://www.gnu.org/licenses/>.                                          --
  26 --                                                                          --
  27 -- GNARL was developed by the GNARL team at Florida State University.       --
  28 -- Extensive contributions were provided by Ada Core Technologies, Inc.     --
  29 --                                                                          --
  30 ------------------------------------------------------------------------------
  31 
  32 with System.Task_Info;
  33 --  Use for Unspecified_Task_Info
  34 
  35 with System.Soft_Links;
  36 --  used to initialize TSD for a C thread, in function Self
  37 
  38 with System.Multiprocessors;
  39 
  40 separate (System.Task_Primitives.Operations)
  41 function Register_Foreign_Thread (Thread : Thread_Id) return Task_Id is
  42    Local_ATCB : aliased Ada_Task_Control_Block (0);
  43    Self_Id    : Task_Id;
  44    Succeeded  : Boolean;
  45 
  46 begin
  47    --  This section is tricky. We must not call anything that might require
  48    --  an ATCB, until the new ATCB is in place. In order to get an ATCB
  49    --  immediately, we fake one, so that it is then possible to e.g allocate
  50    --  memory (which might require accessing self).
  51 
  52    --  Record this as the Task_Id for the thread
  53 
  54    Local_ATCB.Common.LL.Thread := Thread;
  55    Local_ATCB.Common.Current_Priority := System.Priority'First;
  56    Specific.Set (Local_ATCB'Unchecked_Access);
  57 
  58    --  It is now safe to use an allocator
  59 
  60    Self_Id := new Ada_Task_Control_Block (0);
  61 
  62    --  Finish initialization
  63 
  64    Lock_RTS;
  65    System.Tasking.Initialize_ATCB
  66      (Self_Id, null, Null_Address, Null_Task,
  67       Foreign_Task_Elaborated'Access,
  68       System.Priority'First, System.Multiprocessors.Not_A_Specific_CPU, null,
  69       Task_Info.Unspecified_Task_Info, 0, Self_Id, Succeeded);
  70    Unlock_RTS;
  71    pragma Assert (Succeeded);
  72 
  73    Self_Id.Master_of_Task := 0;
  74    Self_Id.Master_Within := Self_Id.Master_of_Task + 1;
  75 
  76    for L in Self_Id.Entry_Calls'Range loop
  77       Self_Id.Entry_Calls (L).Self := Self_Id;
  78       Self_Id.Entry_Calls (L).Level := L;
  79    end loop;
  80 
  81    Self_Id.Common.State := Runnable;
  82    Self_Id.Awake_Count := 1;
  83 
  84    Self_Id.Common.Task_Image (1 .. 14) := "foreign thread";
  85    Self_Id.Common.Task_Image_Len := 14;
  86 
  87    --  Since this is not an ordinary Ada task, we will start out undeferred
  88 
  89    Self_Id.Deferral_Level := 0;
  90 
  91    --  We do not provide an alternate stack for foreign threads
  92 
  93    Self_Id.Common.Task_Alternate_Stack := Null_Address;
  94 
  95    System.Soft_Links.Create_TSD (Self_Id.Common.Compiler_Data);
  96 
  97    Enter_Task (Self_Id);
  98 
  99    return Self_Id;
 100 end Register_Foreign_Thread;