------------------------------------------------------------------------------
--                                                                          --
--                GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS               --
--                                                                          --
--                   SYSTEM.TASK_PRIMITIVES.OPERATIONS.SELF                 --
--                                                                          --
--                                  B o d y                                 --
--                                                                          --
--                             $Revision: 1.2 $                             --
--                                                                          --
--            Copyright (C) 1991-1998, Florida State University             --
--                                                                          --
-- GNARL is free software; you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 2,  or (at your option) any later ver- --
-- sion. GNARL is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License  distributed with GNARL; see file COPYING.  If not, write --
-- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
-- MA 02111-1307, USA.                                                      --
--                                                                          --
-- As a special exception,  if other files  instantiate  generics from this --
-- unit, or you link  this unit with other files  to produce an executable, --
-- this  unit  does not  by itself cause  the resulting  executable  to  be --
-- covered  by the  GNU  General  Public  License.  This exception does not --
-- however invalidate  any other reasons why  the executable file  might be --
-- covered by the  GNU Public License.                                      --
--                                                                          --
-- GNARL was developed by the GNARL team at Florida State University. It is --
-- now maintained by Ada Core Technologies Inc. in cooperation with Florida --
-- State University (http://www.gnat.com).                                  --
--                                                                          --
------------------------------------------------------------------------------

--  This is a Solaris Sparc (native) version of this package.

with System.Machine_Code;
--  used for Asm

separate (System.Task_Primitives.Operations)

----------
-- Self --
----------

--  For Solaris version of RTS, we use a short cut to get the self
--  information faster:

--  We have noticed that on Sparc Solaris, the register g7 always
--  contains the address near the frame pointer (fp) of the active
--  thread (fixed offset). This means, if we declare a variable near
--  the top of the stack for each threads (in our case in the task wrapper)
--  and let the variable hold the Task_ID information, we can get the
--  value without going through the thr_getspecific kernel call.
--
--  There are two things to take care in this trick.
--
--  1) We need to calculate the offset between the g7 value and the
--     local variable address.
--     Possible Solutions :
--        a) Use gdb to figure out the offset.
--        b) Figure it out during the elaboration of RTS by, say,
--           creating a dummy task.
--     We used solution a) mainly because it is more efficient and keeps
--     the RTS from being cluttered with stuff that we won't be used
--     for all environments (i.e., we would have to at least introduce
--     new interfaces).
--
--     On Sparc Solaris the offset was #10#108# (= #16#6b#) with gcc 2.7.2.
--     With gcc 2.8.0, the offset is #10#116# (= #16#74#).
--
--  2) We can not use the same offset business for the main thread
--     because we do not use a wrapper for the main thread.
--     Previousely, we used the difference between g7 and fp to determine
--     wether a task was the main task or not. But this was obviousely
--     wrong since it worked only for tasks that use small amount of
--     stack.
--     So, we now take advantage of the code that recognizes foreign
--     threads (see below) for the main task.
--
--  NOTE: What we are doing here is ABSOLUTELY for Solaris 2.4, 2.5 and 2.6
--        on Sun.

--        We need to make sure this is OK when we move to other versions
--        of the same OS.

--        We always can go back to the old way of doing this and we include
--        the code which use thr_getspecifics. Also, look for %%%%%
--        in comments for other necessary modifications.

--        This code happens to work with Solaris 2.5.1 too, but with gcc
--        2.8.0, this offset is different.

--        ??? Try to rethink the approach here to get a more flexible
--        solution at run time ?

--        One other solution (close to 1-b) would be to add some scanning
--        routine in Enter_Task to compute the offset since now we have
--        a magic number at the beginning of the task code.

--  function Self return Task_ID is
--     Temp   : aliased System.Address;
--     Result : Interfaces.C.int;
--
--  begin
--     Result := thr_getspecific (ATCB_Key, Temp'Unchecked_Access);
--     pragma Assert (Result = 0);
--     return To_Task_ID (Temp);
--  end Self;

--  To make Ada tasks and C threads interoperate better, we have
--  added some functionality to Self.  Suppose a C main program
--  (with threads) calls an Ada procedure and the Ada procedure
--  calls the tasking run-time system.  Eventually, a call will be
--  made to self.  Since the call is not coming from an Ada task,
--  there will be no corresponding ATCB.

--  (The entire Ada run-time system may not have been elaborated,
--  either, but that is a different problem, that we will need to
--  solve another way.)

--  What we do in Self is to catch references that do not come
--  from recognized Ada tasks, and create an ATCB for the calling
--  thread.

--  The new ATCB will be "detached" from the normal Ada task
--  master hierarchy, much like the existing implicitly created
--  signal-server tasks.

--  We will also use such points to poll for disappearance of the
--  threads associated with any implicit ATCBs that we created
--  earlier, and take the opportunity to recover them.

--  A nasty problem here is the limitations of the compilation
--  order dependency, and in particular the GNARL/GNULLI layering.
--  To initialize an ATCB we need to assume System.Tasking has
--  been elaborated.

function Self return Task_ID is
   X      : Ptr;
   Result : Interfaces.C.int;

   function Get_G7 return Interfaces.C.unsigned;
   pragma Inline (Get_G7);

   use System.Machine_Code;

   ------------
   -- Get_G7 --
   ------------

   function Get_G7 return Interfaces.C.unsigned is
      Result : Interfaces.C.unsigned;

   begin
      Asm ("mov %%g7,%0", Interfaces.C.unsigned'Asm_Output ("=r", Result));
      return Result;
   end Get_G7;

--  Start of processing for Self

begin
   if To_Iptr (Get_G7 - 120).all /=
     Interfaces.C.unsigned (ATCB_Magic_Code)
   then
      --  Check whether this is a thread we have seen before (e.g the
      --  main task).
      --  120 = 116 + Magic_Type'Size/System.Storage_Unit

      declare
         Unknown_Task : aliased System.Address;

      begin
         Result :=
           thr_getspecific (ATCB_Key, Unknown_Task'Unchecked_Access);

         pragma Assert (Result = 0);

         if Unknown_Task = System.Null_Address then

            --  We are seeing this thread for the first time.

            return New_Fake_ATCB (Get_G7);

         else
            return To_Task_ID (Unknown_Task);
         end if;
      end;
   end if;

   X := To_Ptr (Get_G7 - 116);
   return X.all;

end Self;
