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>
* ug_words: Add /MULTI_UNIT_INDEX= -> -gnateI
......
......@@ -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
......
......@@ -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)
......
......@@ -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);
......
......@@ -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;
......
......@@ -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
......
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