OSDN Git Service

2009-08-10 Robert Dewar <dewar@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / s-taprop-mingw.adb
index adf1a31..cb51841 100644 (file)
@@ -6,25 +6,23 @@
 --                                                                          --
 --                                  B o d y                                 --
 --                                                                          --
---          Copyright (C) 1992-2008, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2009, Free Software Foundation, Inc.         --
 --                                                                          --
 -- 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- --
+-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
+-- sion.  GNAT 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,  51  Franklin  Street,  Fifth  Floor, --
--- Boston, MA 02110-1301, USA.                                              --
+-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
 --                                                                          --
--- 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.                                      --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception,   --
+-- version 3.1, as published by the Free Software Foundation.               --
+--                                                                          --
+-- You should have received a copy of the GNU General Public License and    --
+-- a copy of the GCC Runtime Library Exception along with this program;     --
+-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
+-- <http://www.gnu.org/licenses/>.                                          --
 --                                                                          --
 -- GNARL was developed by the GNARL team at Florida State University.       --
 -- Extensive contributions were provided by Ada Core Technologies, Inc.     --
@@ -49,6 +47,7 @@ with System.Tasking.Debug;
 with System.OS_Primitives;
 with System.Task_Info;
 with System.Interrupt_Management;
+with System.Win32.Ext;
 
 with System.Soft_Links;
 --  We use System.Soft_Links instead of System.Tasking.Initialization because
@@ -68,6 +67,8 @@ package body System.Task_Primitives.Operations is
    use System.Parameters;
    use System.OS_Primitives;
    use System.Task_Info;
+   use System.Win32;
+   use System.Win32.Ext;
 
    pragma Link_With ("-Xlinker --stack=0x200000,0x1000");
    --  Change the default stack size (2 MB) for tasking programs on Windows.
@@ -76,6 +77,30 @@ package body System.Task_Primitives.Operations is
    --  Also note that under Windows XP, we use a Windows XP extension to
    --  specify the stack size on a per task basis, as done under other OSes.
 
+   ---------------------
+   -- Local Functions --
+   ---------------------
+
+   procedure InitializeCriticalSection (pCriticalSection : access RTS_Lock);
+   procedure InitializeCriticalSection
+     (pCriticalSection : access CRITICAL_SECTION);
+   pragma Import
+     (Stdcall, InitializeCriticalSection, "InitializeCriticalSection");
+
+   procedure EnterCriticalSection (pCriticalSection : access RTS_Lock);
+   procedure EnterCriticalSection
+     (pCriticalSection : access CRITICAL_SECTION);
+   pragma Import (Stdcall, EnterCriticalSection, "EnterCriticalSection");
+
+   procedure LeaveCriticalSection (pCriticalSection : access RTS_Lock);
+   procedure LeaveCriticalSection (pCriticalSection : access CRITICAL_SECTION);
+   pragma Import (Stdcall, LeaveCriticalSection, "LeaveCriticalSection");
+
+   procedure DeleteCriticalSection (pCriticalSection : access RTS_Lock);
+   procedure DeleteCriticalSection
+     (pCriticalSection : access CRITICAL_SECTION);
+   pragma Import (Stdcall, DeleteCriticalSection, "DeleteCriticalSection");
+
    ----------------
    -- Local Data --
    ----------------
@@ -140,7 +165,7 @@ package body System.Task_Primitives.Operations is
          Succeeded : BOOL;
       begin
          Succeeded := TlsSetValue (TlsIndex, To_Address (Self_Id));
-         pragma Assert (Succeeded = True);
+         pragma Assert (Succeeded = Win32.TRUE);
       end Set;
 
    end Specific;
@@ -192,7 +217,7 @@ package body System.Task_Primitives.Operations is
    procedure Initialize_Cond (Cond : not null access Condition_Variable) is
       hEvent : HANDLE;
    begin
-      hEvent := CreateEvent (null, True, False, Null_Ptr);
+      hEvent := CreateEvent (null, Win32.TRUE, Win32.FALSE, Null_Ptr);
       pragma Assert (hEvent /= 0);
       Cond.all := Condition_Variable (hEvent);
    end Initialize_Cond;
@@ -208,7 +233,7 @@ package body System.Task_Primitives.Operations is
       Result : BOOL;
    begin
       Result := CloseHandle (HANDLE (Cond.all));
-      pragma Assert (Result = True);
+      pragma Assert (Result = Win32.TRUE);
    end Finalize_Cond;
 
    -----------------
@@ -219,7 +244,7 @@ package body System.Task_Primitives.Operations is
       Result : BOOL;
    begin
       Result := SetEvent (HANDLE (Cond.all));
-      pragma Assert (Result = True);
+      pragma Assert (Result = Win32.TRUE);
    end Cond_Signal;
 
    ---------------
@@ -243,7 +268,7 @@ package body System.Task_Primitives.Operations is
       --  Must reset Cond BEFORE L is unlocked
 
       Result_Bool := ResetEvent (HANDLE (Cond.all));
-      pragma Assert (Result_Bool = True);
+      pragma Assert (Result_Bool = Win32.TRUE);
       Unlock (L, Global_Lock => True);
 
       --  No problem if we are interrupted here: if the condition is signaled,
@@ -283,7 +308,7 @@ package body System.Task_Primitives.Operations is
       --  Must reset Cond BEFORE L is unlocked
 
       Result := ResetEvent (HANDLE (Cond.all));
-      pragma Assert (Result = True);
+      pragma Assert (Result = Win32.TRUE);
       Unlock (L, Global_Lock => True);
 
       --  No problem if we are interrupted here: if the condition is signaled,
@@ -316,7 +341,7 @@ package body System.Task_Primitives.Operations is
 
       if Timed_Out then
          Result := SetEvent (HANDLE (Cond.all));
-         pragma Assert (Result = True);
+         pragma Assert (Result = Win32.TRUE);
       end if;
 
       Status := Integer (Wait_Result);
@@ -364,7 +389,7 @@ package body System.Task_Primitives.Operations is
    ---------------------
 
    --  Note: mutexes and cond_variables needed per-task basis are initialized
-   --  in Intialize_TCB and the Storage_Error is handled. Other mutexes (such
+   --  in Initialize_TCB and the Storage_Error is handled. Other mutexes (such
    --  as RTS_Lock, Memory_Lock...) used in the RTS is initialized before any
    --  status change of RTS. Therefore raising Storage_Error in the following
    --  routines should be able to be handled safely.
@@ -384,7 +409,7 @@ package body System.Task_Primitives.Operations is
    is
       pragma Unreferenced (Level);
    begin
-      InitializeCriticalSection (CRITICAL_SECTION (L.all)'Unrestricted_Access);
+      InitializeCriticalSection (L);
    end Initialize_Lock;
 
    -------------------
@@ -398,7 +423,7 @@ package body System.Task_Primitives.Operations is
 
    procedure Finalize_Lock (L : not null access RTS_Lock) is
    begin
-      DeleteCriticalSection (CRITICAL_SECTION (L.all)'Unrestricted_Access);
+      DeleteCriticalSection (L);
    end Finalize_Lock;
 
    ----------------
@@ -426,15 +451,14 @@ package body System.Task_Primitives.Operations is
    is
    begin
       if not Single_Lock or else Global_Lock then
-         EnterCriticalSection (CRITICAL_SECTION (L.all)'Unrestricted_Access);
+         EnterCriticalSection (L);
       end if;
    end Write_Lock;
 
    procedure Write_Lock (T : Task_Id) is
    begin
       if not Single_Lock then
-         EnterCriticalSection
-           (CRITICAL_SECTION (T.Common.LL.L)'Unrestricted_Access);
+         EnterCriticalSection (T.Common.LL.L'Access);
       end if;
    end Write_Lock;
 
@@ -461,15 +485,14 @@ package body System.Task_Primitives.Operations is
      (L : not null access RTS_Lock; Global_Lock : Boolean := False) is
    begin
       if not Single_Lock or else Global_Lock then
-         LeaveCriticalSection (CRITICAL_SECTION (L.all)'Unrestricted_Access);
+         LeaveCriticalSection (L);
       end if;
    end Unlock;
 
    procedure Unlock (T : Task_Id) is
    begin
       if not Single_Lock then
-         LeaveCriticalSection
-           (CRITICAL_SECTION (T.Common.LL.L)'Unrestricted_Access);
+         LeaveCriticalSection (T.Common.LL.L'Access);
       end if;
    end Unlock;
 
@@ -708,7 +731,7 @@ package body System.Task_Primitives.Operations is
    begin
       Res := SetThreadPriority
         (T.Common.LL.Thread, Interfaces.C.int (Underlying_Priorities (Prio)));
-      pragma Assert (Res = True);
+      pragma Assert (Res = Win32.TRUE);
 
       if Dispatching_Policy = 'F' or else Get_Policy (Prio) = 'F' then
 
@@ -763,7 +786,7 @@ package body System.Task_Primitives.Operations is
 
    --  This is because the GetCurrentThread NT call does not return the real
    --  thread handler but only a "pseudo" one. It is not possible to release
-   --  the thread handle and free the system ressources from this "pseudo"
+   --  the thread handle and free the system resources from this "pseudo"
    --  handle. So we really want to keep the real thread handle set in
    --  System.Task_Primitives.Operations.Create_Task during thread creation.
 
@@ -784,18 +807,6 @@ package body System.Task_Primitives.Operations is
       end if;
 
       Self_ID.Common.LL.Thread_Id := GetCurrentThreadId;
-
-      Lock_RTS;
-
-      for J in Known_Tasks'Range loop
-         if Known_Tasks (J) = null then
-            Known_Tasks (J) := Self_ID;
-            Self_ID.Known_Tasks_Index := J;
-            exit;
-         end if;
-      end loop;
-
-      Unlock_RTS;
    end Enter_Task;
 
    --------------
@@ -869,7 +880,7 @@ package body System.Task_Primitives.Operations is
 
       hTask          : HANDLE;
       TaskId         : aliased DWORD;
-      pTaskParameter : System.OS_Interface.PVOID;
+      pTaskParameter : Win32.PVOID;
       Result         : DWORD;
       Entry_Point    : PTHREAD_START_ROUTINE;
 
@@ -920,7 +931,7 @@ package body System.Task_Primitives.Operations is
          --  boost. A priority boost is temporarily given by the system to a
          --  thread when it is taken out of a wait state.
 
-         SetThreadPriorityBoost (hTask, DisablePriorityBoost => True);
+         SetThreadPriorityBoost (hTask, DisablePriorityBoost => Win32.TRUE);
       end if;
 
       --  Step 4: Handle Task_Info
@@ -967,12 +978,12 @@ package body System.Task_Primitives.Operations is
       if Self_ID.Common.LL.Thread /= 0 then
 
          --  This task has been activated. Wait for the thread to terminate
-         --  then close it. this is needed to release system ressources.
+         --  then close it. This is needed to release system resources.
 
          Result := WaitForSingleObject (T.Common.LL.Thread, Wait_Infinite);
          pragma Assert (Result /= WAIT_FAILED);
          Succeeded := CloseHandle (T.Common.LL.Thread);
-         pragma Assert (Succeeded = True);
+         pragma Assert (Succeeded = Win32.TRUE);
       end if;
 
       Free (Self_ID);
@@ -1058,6 +1069,13 @@ package body System.Task_Primitives.Operations is
       Initialize_Lock (Single_RTS_Lock'Access, RTS_Lock_Level);
 
       Environment_Task.Common.LL.Thread := GetCurrentThread;
+
+      --  Make environment task known here because it doesn't go through
+      --  Activate_Tasks, which does it for all other tasks.
+
+      Known_Tasks (Known_Tasks'First) := Environment_Task;
+      Environment_Task.Known_Tasks_Index := Known_Tasks'First;
+
       Enter_Task (Environment_Task);
    end Initialize;
 
@@ -1095,7 +1113,7 @@ package body System.Task_Primitives.Operations is
 
       --  Initialize internal condition variable
 
-      S.CV := CreateEvent (null, True, False, Null_Ptr);
+      S.CV := CreateEvent (null, Win32.TRUE, Win32.FALSE, Null_Ptr);
       pragma Assert (S.CV /= 0);
    end Initialize;
 
@@ -1113,7 +1131,7 @@ package body System.Task_Primitives.Operations is
       --  Destroy internal condition variable
 
       Result := CloseHandle (S.CV);
-      pragma Assert (Result = True);
+      pragma Assert (Result = Win32.TRUE);
    end Finalize;
 
    -------------------
@@ -1166,7 +1184,7 @@ package body System.Task_Primitives.Operations is
          S.State := False;
 
          Result := SetEvent (S.CV);
-         pragma Assert (Result = True);
+         pragma Assert (Result = Win32.TRUE);
       else
          S.State := True;
       end if;
@@ -1215,7 +1233,7 @@ package body System.Task_Primitives.Operations is
             --  Must reset CV BEFORE L is unlocked
 
             Result_Bool := ResetEvent (S.CV);
-            pragma Assert (Result_Bool = True);
+            pragma Assert (Result_Bool = Win32.TRUE);
 
             LeaveCriticalSection (S.L'Access);