2011-09-01 Jose Ruiz <ruiz@adacore.com>
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 1 Sep 2011 13:40:48 +0000 (13:40 +0000)
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 1 Sep 2011 13:40:48 +0000 (13:40 +0000)
* adaint.c, adaint.h (__gnat_cpu_alloc, __gnat_cpu_alloc_size,
__gnat_cpu_set_free): Create these wrappers around the CPU_ALLOC,
CPU_ALLOC_SIZE and CPU_FREE linux macros.
(__gnat_cpu_zero, __gnat_cpu_set): Use the CPU_ZERO_S and
CPU_SET_S respectively because we are now using dynamically allocated
CPU sets which are more portable across different glibc versions.
* s-osinte-linux.ads (cpu_set_t_ptr, CPU_ALLOC, CPU_ALLOC_SIZE,
CPU_FREE): Add this type and subprograms to be able to create cpu_set_t
masks dynamically according to the number of processors in the target
platform.
(CPU_ZERO, CPU_SET): They are now mapped to the CPU_ZERO_S and CPU_SET_S
respectively, so we need to pass the size of the masks as
parameters.
* s-taprop-linux.adb (Create_Task, Set_Task_Affinity): Use dynamically
created cpu_set_t masks
with the number of processors available in the target platform,
instead of static bit arrays. It enhances portability because
it uses the information from the target platform.
* sem_ch8.adb: (Attribute_Renaming): When checking whether we
are using a restricted run-time library, use the flag
Configurable_Run_Time_Mode instead of Restricted_Profile.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@178416 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ada/ChangeLog
gcc/ada/adaint.c
gcc/ada/adaint.h
gcc/ada/s-osinte-linux.ads
gcc/ada/s-taprop-linux.adb
gcc/ada/sem_ch8.adb

index 373f901..c3cff67 100644 (file)
@@ -1,3 +1,27 @@
+2011-09-01  Jose Ruiz  <ruiz@adacore.com>
+
+       * adaint.c, adaint.h (__gnat_cpu_alloc, __gnat_cpu_alloc_size,
+       __gnat_cpu_set_free): Create these wrappers around the CPU_ALLOC,
+       CPU_ALLOC_SIZE and CPU_FREE linux macros.
+       (__gnat_cpu_zero, __gnat_cpu_set): Use the CPU_ZERO_S and
+       CPU_SET_S respectively because we are now using dynamically allocated
+       CPU sets which are more portable across different glibc versions.
+       * s-osinte-linux.ads (cpu_set_t_ptr, CPU_ALLOC, CPU_ALLOC_SIZE,
+       CPU_FREE): Add this type and subprograms to be able to create cpu_set_t
+       masks dynamically according to the number of processors in the target
+       platform.
+       (CPU_ZERO, CPU_SET): They are now mapped to the CPU_ZERO_S and CPU_SET_S
+       respectively, so we need to pass the size of the masks as
+       parameters.
+       * s-taprop-linux.adb (Create_Task, Set_Task_Affinity): Use dynamically
+       created cpu_set_t masks
+       with the number of processors available in the target platform,
+       instead of static bit arrays. It enhances portability because
+       it uses the information from the target platform.
+       * sem_ch8.adb: (Attribute_Renaming): When checking whether we
+       are using a restricted run-time library, use the flag
+       Configurable_Run_Time_Mode instead of Restricted_Profile.
+
 2011-09-01  Vincent Celier  <celier@adacore.com>
 
        * ug_words: Add /MULTI_UNIT_INDEX= -> -gnateI
index adc702a..605cdaf 100644 (file)
@@ -3790,16 +3790,31 @@ void *__gnat_lwp_self (void)
 
 #include <sched.h>
 
-void __gnat_cpu_zero (cpu_set_t *set)
+cpu_set_t *__gnat_cpu_alloc (size_t count)
 {
-  CPU_ZERO (set);
+  return CPU_ALLOC (count);
 }
 
-void __gnat_cpu_set (int cpu, cpu_set_t *set)
+size_t __gnat_cpu_alloc_size (size_t count)
+{
+  return CPU_ALLOC_SIZE (count);
+}
+
+void __gnat_cpu_free (cpu_set_t *set)
+{
+  CPU_FREE (set);
+}
+
+void __gnat_cpu_zero (size_t count, cpu_set_t *set)
+{
+  CPU_ZERO_S (count, set);
+}
+
+void __gnat_cpu_set (int cpu, size_t count, cpu_set_t *set)
 {
   /* Ada handles CPU numbers starting from 1, while C identifies the first
      CPU by a 0, so we need to adjust. */
-  CPU_SET (cpu - 1, set);
+  CPU_SET_S (cpu - 1, count, set);
 }
 #endif
 
index 45f1203..de00fb6 100644 (file)
@@ -252,8 +252,11 @@ extern void   *__gnat_lwp_self                        (void);
 
 #include <sched.h>
 
-extern void   __gnat_cpu_zero                      (cpu_set_t *);
-extern void   __gnat_cpu_set                       (int, cpu_set_t *);
+extern cpu_set_t *__gnat_cpu_alloc                 (size_t);
+extern size_t __gnat_cpu_alloc_size                (size_t);
+extern void   __gnat_cpu_set_free                  (cpu_set_t *);
+extern void   __gnat_cpu_zero                      (size_t, cpu_set_t *);
+extern void   __gnat_cpu_set                       (int, size_t, cpu_set_t *);
 #endif
 
 #if defined (_WIN32)
index 8e07f38..18a314b 100644 (file)
@@ -471,6 +471,10 @@ package System.OS_Interface is
    pragma Import (C, pthread_key_create, "pthread_key_create");
 
    CPU_SETSIZE : constant := 1_024;
+   --  Size of the cpu_set_t mask on most linux systems (SUSE 11 uses 4_096).
+   --  This is kept for backward compatibility (System.Task_Info uses it), but
+   --  the run-time library does no longer rely on static masks, using
+   --  dynamically allocated masks instead.
 
    type bit_field is array (1 .. CPU_SETSIZE) of Boolean;
    for bit_field'Size use CPU_SETSIZE;
@@ -482,18 +486,36 @@ package System.OS_Interface is
    end record;
    pragma Convention (C, cpu_set_t);
 
-   procedure CPU_ZERO (cpuset : access cpu_set_t);
+   type cpu_set_t_ptr is access all cpu_set_t;
+   --  In the run-time library we use this pointer because the size of type
+   --  cpu_set_t varies depending on the glibc version. Hence, objects of type
+   --  cpu_set_t are allocated dynamically using the number of processors
+   --  available in the target machine (value obtained at execution time).
+
+   function CPU_ALLOC (count : size_t) return cpu_set_t_ptr;
+   pragma Import (C, CPU_ALLOC, "__gnat_cpu_alloc");
+   --  Wrapper around the CPU_ALLOC C macro
+
+   function CPU_ALLOC_SIZE (count : size_t) return size_t;
+   pragma Import (C, CPU_ALLOC_SIZE, "__gnat_cpu_alloc_size");
+   --  Wrapper around the CPU_ALLOC_SIZE C macro
+
+   procedure CPU_FREE (cpuset : cpu_set_t_ptr);
+   pragma Import (C, CPU_FREE, "__gnat_cpu_free");
+   --  Wrapper around the CPU_FREE C macro
+
+   procedure CPU_ZERO (count : size_t; cpuset : cpu_set_t_ptr);
    pragma Import (C, CPU_ZERO, "__gnat_cpu_zero");
-   --  Wrapper around the CPU_ZERO C macro
+   --  Wrapper around the CPU_ZERO_S C macro
 
-   procedure CPU_SET (cpu : int; cpuset : access cpu_set_t);
+   procedure CPU_SET (cpu : int; count : size_t; cpuset : cpu_set_t_ptr);
    pragma Import (C, CPU_SET, "__gnat_cpu_set");
-   --  Wrapper around the CPU_SET C macro
+   --  Wrapper around the CPU_SET_S C macro
 
    function pthread_setaffinity_np
      (thread     : pthread_t;
       cpusetsize : size_t;
-      cpuset     : access cpu_set_t) return int;
+      cpuset     : cpu_set_t_ptr) return int;
    pragma Import (C, pthread_setaffinity_np, "pthread_setaffinity_np");
    pragma Weak_External (pthread_setaffinity_np);
    --  Use a weak symbol because this function may be available or not,
@@ -502,7 +524,7 @@ package System.OS_Interface is
    function pthread_attr_setaffinity_np
      (attr       : access pthread_attr_t;
       cpusetsize : size_t;
-      cpuset     : access cpu_set_t) return int;
+      cpuset     : cpu_set_t_ptr) return int;
    pragma Import (C, pthread_attr_setaffinity_np,
                     "pthread_attr_setaffinity_np");
    pragma Weak_External (pthread_attr_setaffinity_np);
index eced89a..2034566 100644 (file)
@@ -869,25 +869,25 @@ package body System.Task_Primitives.Operations is
 
       elsif T.Common.Base_CPU /= System.Multiprocessors.Not_A_Specific_CPU then
          declare
-            CPU_Set : aliased cpu_set_t;
+            CPUs    : constant size_t :=
+              Interfaces.C.size_t (System.Multiprocessors.Number_Of_CPUs);
+            CPU_Set : constant cpu_set_t_ptr := CPU_ALLOC (CPUs);
+            Size    : constant size_t := CPU_ALLOC_SIZE (CPUs);
 
          begin
-            System.OS_Interface.CPU_ZERO (CPU_Set'Access);
+            CPU_ZERO (Size, CPU_Set);
             System.OS_Interface.CPU_SET
-              (int (T.Common.Base_CPU), CPU_Set'Access);
+              (int (T.Common.Base_CPU), Size, CPU_Set);
             Result :=
-              pthread_attr_setaffinity_np
-                (Attributes'Access,
-                 CPU_SETSIZE / 8,
-                 CPU_Set'Access);
+              pthread_attr_setaffinity_np (Attributes'Access, Size, CPU_Set);
             pragma Assert (Result = 0);
+
+            CPU_FREE (CPU_Set);
          end;
 
       --  Handle Task_Info
 
-      elsif T.Common.Task_Info /= null
-        and then T.Common.Task_Info.CPU_Affinity /= Task_Info.Any_CPU
-      then
+      elsif T.Common.Task_Info /= null then
          Result :=
            pthread_attr_setaffinity_np
              (Attributes'Access,
@@ -908,26 +908,28 @@ package body System.Task_Primitives.Operations is
                      Multiprocessors.Number_Of_CPUs => True))
       then
          declare
-            CPU_Set : aliased cpu_set_t;
+            CPUs    : constant size_t :=
+              Interfaces.C.size_t (System.Multiprocessors.Number_Of_CPUs);
+            CPU_Set : constant cpu_set_t_ptr := CPU_ALLOC (CPUs);
+            Size    : constant size_t := CPU_ALLOC_SIZE (CPUs);
 
          begin
-            System.OS_Interface.CPU_ZERO (CPU_Set'Access);
+            CPU_ZERO (Size, CPU_Set);
 
             --  Set the affinity to all the processors belonging to the
             --  dispatching domain.
 
             for Proc in T.Common.Domain'Range loop
                if T.Common.Domain (Proc) then
-                  System.OS_Interface.CPU_SET (int (Proc), CPU_Set'Access);
+                  System.OS_Interface.CPU_SET (int (Proc), Size, CPU_Set);
                end if;
             end loop;
 
             Result :=
-              pthread_attr_setaffinity_np
-                (Attributes'Access,
-                 CPU_SETSIZE / 8,
-                 CPU_Set'Access);
+              pthread_attr_setaffinity_np (Attributes'Access, Size, CPU_Set);
             pragma Assert (Result = 0);
+
+            CPU_FREE (CPU_Set);
          end;
       end if;
 
@@ -1400,9 +1402,10 @@ package body System.Task_Primitives.Operations is
         and then T.Common.LL.Thread /= Null_Thread_Id
       then
          declare
-            type cpu_set_t_ptr is access all cpu_set_t;
-            CPU_Set : aliased cpu_set_t;
-            CPU_Set_Ptr : cpu_set_t_ptr := null;
+            CPUs    : constant size_t :=
+              Interfaces.C.size_t (System.Multiprocessors.Number_Of_CPUs);
+            CPU_Set : cpu_set_t_ptr := null;
+            Size    : constant size_t := CPU_ALLOC_SIZE (CPUs);
 
             Result  : Interfaces.C.int;
 
@@ -1414,17 +1417,16 @@ package body System.Task_Primitives.Operations is
             if T.Common.Base_CPU /= Multiprocessors.Not_A_Specific_CPU then
 
                --  Set the affinity to an unique CPU
-               System.OS_Interface.CPU_ZERO (CPU_Set'Access);
+
+               CPU_Set := CPU_ALLOC (CPUs);
+               System.OS_Interface.CPU_ZERO (Size, CPU_Set);
                System.OS_Interface.CPU_SET
-                 (int (T.Common.Base_CPU), CPU_Set'Access);
-               CPU_Set_Ptr := CPU_Set'Access;
+                 (int (T.Common.Base_CPU), Size, CPU_Set);
 
             --  Handle Task_Info
 
-            elsif T.Common.Task_Info /= null
-              and then T.Common.Task_Info.CPU_Affinity /= Task_Info.Any_CPU
-            then
-               CPU_Set_Ptr := T.Common.Task_Info.CPU_Affinity'Access;
+            elsif T.Common.Task_Info /= null then
+               CPU_Set := T.Common.Task_Info.CPU_Affinity'Access;
 
             --  Handle dispatching domains
 
@@ -1440,13 +1442,12 @@ package body System.Task_Primitives.Operations is
                --  domain other than the default one, or when the default one
                --  has been modified.
 
-               System.OS_Interface.CPU_ZERO (CPU_Set'Access);
+               CPU_Set := CPU_ALLOC (CPUs);
+               System.OS_Interface.CPU_ZERO (Size, CPU_Set);
 
                for Proc in T.Common.Domain'Range loop
-                  System.OS_Interface.CPU_SET (int (Proc), CPU_Set'Access);
+                  System.OS_Interface.CPU_SET (int (Proc), Size, CPU_Set);
                end loop;
-
-               CPU_Set_Ptr := CPU_Set'Access;
             end if;
 
             --  We set the new affinity if needed. Otherwise, the new task
@@ -1454,11 +1455,12 @@ package body System.Task_Primitives.Operations is
             --  the documentation of pthread_setaffinity_np), which is
             --  consistent with Ada's required semantics.
 
-            if CPU_Set_Ptr /= null then
+            if CPU_Set /= null then
                Result :=
-                 pthread_setaffinity_np
-                   (T.Common.LL.Thread, CPU_SETSIZE / 8, CPU_Set_Ptr);
+                 pthread_setaffinity_np (T.Common.LL.Thread, Size, CPU_Set);
                pragma Assert (Result = 0);
+
+               CPU_FREE (CPU_Set);
             end if;
          end;
       end if;
index 3a58a8f..796f9b0 100644 (file)
@@ -3292,10 +3292,13 @@ package body Sem_Ch8 is
 
       --  We must exclude VM targets and restricted run-time libraries because
       --  entity AST_Handler is defined in package System.Aux_Dec which is not
-      --  available in those platforms.
+      --  available in those platforms. Note that we cannot use the function
+      --  Restricted_Profile (instead of Configurable_Run_Time_Mode) because
+      --  the ZFP run-time library is not defined as a profile, and we do not
+      --  want to deal with AST_Handler in ZFP mode.
 
       if VM_Target = No_VM
-        and then not Restricted_Profile
+        and then not Configurable_Run_Time_Mode
         and then not Present (Corresponding_Formal_Spec (N))
         and then Etype (Nam) /= RTE (RE_AST_Handler)
       then