Commit 9d1e0e72 by Jose Ruiz Committed by Arnaud Charlet

adaint.c, adaint.h (__gnat_cpu_alloc, [...]): Create these wrappers around the CPU_ALLOC...

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.

From-SVN: r178416
parent a95be2d4
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> 2011-09-01 Vincent Celier <celier@adacore.com>
* ug_words: Add /MULTI_UNIT_INDEX= -> -gnateI * ug_words: Add /MULTI_UNIT_INDEX= -> -gnateI
......
...@@ -3790,16 +3790,31 @@ void *__gnat_lwp_self (void) ...@@ -3790,16 +3790,31 @@ void *__gnat_lwp_self (void)
#include <sched.h> #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 /* Ada handles CPU numbers starting from 1, while C identifies the first
CPU by a 0, so we need to adjust. */ CPU by a 0, so we need to adjust. */
CPU_SET (cpu - 1, set); CPU_SET_S (cpu - 1, count, set);
} }
#endif #endif
......
...@@ -252,8 +252,11 @@ extern void *__gnat_lwp_self (void); ...@@ -252,8 +252,11 @@ extern void *__gnat_lwp_self (void);
#include <sched.h> #include <sched.h>
extern void __gnat_cpu_zero (cpu_set_t *); extern cpu_set_t *__gnat_cpu_alloc (size_t);
extern void __gnat_cpu_set (int, cpu_set_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 #endif
#if defined (_WIN32) #if defined (_WIN32)
......
...@@ -471,6 +471,10 @@ package System.OS_Interface is ...@@ -471,6 +471,10 @@ package System.OS_Interface is
pragma Import (C, pthread_key_create, "pthread_key_create"); pragma Import (C, pthread_key_create, "pthread_key_create");
CPU_SETSIZE : constant := 1_024; 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; type bit_field is array (1 .. CPU_SETSIZE) of Boolean;
for bit_field'Size use CPU_SETSIZE; for bit_field'Size use CPU_SETSIZE;
...@@ -482,18 +486,36 @@ package System.OS_Interface is ...@@ -482,18 +486,36 @@ package System.OS_Interface is
end record; end record;
pragma Convention (C, cpu_set_t); 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"); 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"); 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 function pthread_setaffinity_np
(thread : pthread_t; (thread : pthread_t;
cpusetsize : size_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 Import (C, pthread_setaffinity_np, "pthread_setaffinity_np");
pragma Weak_External (pthread_setaffinity_np); pragma Weak_External (pthread_setaffinity_np);
-- Use a weak symbol because this function may be available or not, -- Use a weak symbol because this function may be available or not,
...@@ -502,7 +524,7 @@ package System.OS_Interface is ...@@ -502,7 +524,7 @@ package System.OS_Interface is
function pthread_attr_setaffinity_np function pthread_attr_setaffinity_np
(attr : access pthread_attr_t; (attr : access pthread_attr_t;
cpusetsize : size_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, pragma Import (C, pthread_attr_setaffinity_np,
"pthread_attr_setaffinity_np"); "pthread_attr_setaffinity_np");
pragma Weak_External (pthread_attr_setaffinity_np); pragma Weak_External (pthread_attr_setaffinity_np);
......
...@@ -869,25 +869,25 @@ package body System.Task_Primitives.Operations is ...@@ -869,25 +869,25 @@ package body System.Task_Primitives.Operations is
elsif T.Common.Base_CPU /= System.Multiprocessors.Not_A_Specific_CPU then elsif T.Common.Base_CPU /= System.Multiprocessors.Not_A_Specific_CPU then
declare 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 begin
System.OS_Interface.CPU_ZERO (CPU_Set'Access); CPU_ZERO (Size, CPU_Set);
System.OS_Interface.CPU_SET System.OS_Interface.CPU_SET
(int (T.Common.Base_CPU), CPU_Set'Access); (int (T.Common.Base_CPU), Size, CPU_Set);
Result := Result :=
pthread_attr_setaffinity_np pthread_attr_setaffinity_np (Attributes'Access, Size, CPU_Set);
(Attributes'Access,
CPU_SETSIZE / 8,
CPU_Set'Access);
pragma Assert (Result = 0); pragma Assert (Result = 0);
CPU_FREE (CPU_Set);
end; end;
-- Handle Task_Info -- Handle Task_Info
elsif T.Common.Task_Info /= null elsif T.Common.Task_Info /= null then
and then T.Common.Task_Info.CPU_Affinity /= Task_Info.Any_CPU
then
Result := Result :=
pthread_attr_setaffinity_np pthread_attr_setaffinity_np
(Attributes'Access, (Attributes'Access,
...@@ -908,26 +908,28 @@ package body System.Task_Primitives.Operations is ...@@ -908,26 +908,28 @@ package body System.Task_Primitives.Operations is
Multiprocessors.Number_Of_CPUs => True)) Multiprocessors.Number_Of_CPUs => True))
then then
declare 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 begin
System.OS_Interface.CPU_ZERO (CPU_Set'Access); CPU_ZERO (Size, CPU_Set);
-- Set the affinity to all the processors belonging to the -- Set the affinity to all the processors belonging to the
-- dispatching domain. -- dispatching domain.
for Proc in T.Common.Domain'Range loop for Proc in T.Common.Domain'Range loop
if T.Common.Domain (Proc) then 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 if;
end loop; end loop;
Result := Result :=
pthread_attr_setaffinity_np pthread_attr_setaffinity_np (Attributes'Access, Size, CPU_Set);
(Attributes'Access,
CPU_SETSIZE / 8,
CPU_Set'Access);
pragma Assert (Result = 0); pragma Assert (Result = 0);
CPU_FREE (CPU_Set);
end; end;
end if; end if;
...@@ -1400,9 +1402,10 @@ package body System.Task_Primitives.Operations is ...@@ -1400,9 +1402,10 @@ package body System.Task_Primitives.Operations is
and then T.Common.LL.Thread /= Null_Thread_Id and then T.Common.LL.Thread /= Null_Thread_Id
then then
declare declare
type cpu_set_t_ptr is access all cpu_set_t; CPUs : constant size_t :=
CPU_Set : aliased cpu_set_t; Interfaces.C.size_t (System.Multiprocessors.Number_Of_CPUs);
CPU_Set_Ptr : cpu_set_t_ptr := null; CPU_Set : cpu_set_t_ptr := null;
Size : constant size_t := CPU_ALLOC_SIZE (CPUs);
Result : Interfaces.C.int; Result : Interfaces.C.int;
...@@ -1414,17 +1417,16 @@ package body System.Task_Primitives.Operations is ...@@ -1414,17 +1417,16 @@ package body System.Task_Primitives.Operations is
if T.Common.Base_CPU /= Multiprocessors.Not_A_Specific_CPU then if T.Common.Base_CPU /= Multiprocessors.Not_A_Specific_CPU then
-- Set the affinity to an unique CPU -- 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 System.OS_Interface.CPU_SET
(int (T.Common.Base_CPU), CPU_Set'Access); (int (T.Common.Base_CPU), Size, CPU_Set);
CPU_Set_Ptr := CPU_Set'Access;
-- Handle Task_Info -- Handle Task_Info
elsif T.Common.Task_Info /= null elsif T.Common.Task_Info /= null then
and then T.Common.Task_Info.CPU_Affinity /= Task_Info.Any_CPU CPU_Set := T.Common.Task_Info.CPU_Affinity'Access;
then
CPU_Set_Ptr := T.Common.Task_Info.CPU_Affinity'Access;
-- Handle dispatching domains -- Handle dispatching domains
...@@ -1440,13 +1442,12 @@ package body System.Task_Primitives.Operations is ...@@ -1440,13 +1442,12 @@ package body System.Task_Primitives.Operations is
-- domain other than the default one, or when the default one -- domain other than the default one, or when the default one
-- has been modified. -- 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 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; end loop;
CPU_Set_Ptr := CPU_Set'Access;
end if; end if;
-- We set the new affinity if needed. Otherwise, the new task -- We set the new affinity if needed. Otherwise, the new task
...@@ -1454,11 +1455,12 @@ package body System.Task_Primitives.Operations is ...@@ -1454,11 +1455,12 @@ package body System.Task_Primitives.Operations is
-- the documentation of pthread_setaffinity_np), which is -- the documentation of pthread_setaffinity_np), which is
-- consistent with Ada's required semantics. -- consistent with Ada's required semantics.
if CPU_Set_Ptr /= null then if CPU_Set /= null then
Result := Result :=
pthread_setaffinity_np pthread_setaffinity_np (T.Common.LL.Thread, Size, CPU_Set);
(T.Common.LL.Thread, CPU_SETSIZE / 8, CPU_Set_Ptr);
pragma Assert (Result = 0); pragma Assert (Result = 0);
CPU_FREE (CPU_Set);
end if; end if;
end; end;
end if; end if;
......
...@@ -3292,10 +3292,13 @@ package body Sem_Ch8 is ...@@ -3292,10 +3292,13 @@ package body Sem_Ch8 is
-- We must exclude VM targets and restricted run-time libraries because -- We must exclude VM targets and restricted run-time libraries because
-- entity AST_Handler is defined in package System.Aux_Dec which is not -- 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 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 not Present (Corresponding_Formal_Spec (N))
and then Etype (Nam) /= RTE (RE_AST_Handler) and then Etype (Nam) /= RTE (RE_AST_Handler)
then then
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment