CPU sets are properly handled in linux using the macros defined for this effect. This way we avoid problems with the endianness of the target if we try to modify the bit set by hand.
No functional change. Tested on x86_64-pc-linux-gnu, committed on trunk 2011-09-01 Jose Ruiz <r...@adacore.com> * s-taprop-linux.adb (Create_Task, Set_Task_Affinity): Use the linux macros for handling CPU sets (CPU_ZERO, CPU_SET) instead of modifying directly the bit array. * s-osinte-linux.ads (CPU_ZERO, CPU_SET): Import these wrappers around the linux macros with the same name. * adaint.h, adaint.c (__gnat_cpu_zero, __gnat_cpu_set): Create these wrappers around the CPU_ZERO and CPU_SET linux macros.
Index: s-osinte-linux.ads =================================================================== --- s-osinte-linux.ads (revision 178381) +++ s-osinte-linux.ads (working copy) @@ -7,7 +7,7 @@ -- S p e c -- -- -- -- Copyright (C) 1991-1994, Florida State University -- --- Copyright (C) 1995-2010, Free Software Foundation, Inc. -- +-- Copyright (C) 1995-2011, Free Software Foundation, Inc. -- -- -- -- GNAT 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- -- @@ -482,6 +482,14 @@ end record; pragma Convention (C, cpu_set_t); + procedure CPU_ZERO (cpuset : access cpu_set_t); + pragma Import (C, CPU_ZERO, "__gnat_cpu_zero"); + -- Wrapper around the CPU_ZERO C macro + + procedure CPU_SET (cpu : int; cpuset : access cpu_set_t); + pragma Import (C, CPU_SET, "__gnat_cpu_set"); + -- Wrapper around the CPU_SET C macro + function pthread_setaffinity_np (thread : pthread_t; cpusetsize : size_t; Index: s-taprop-linux.adb =================================================================== --- s-taprop-linux.adb (revision 178398) +++ s-taprop-linux.adb (working copy) @@ -869,9 +869,12 @@ elsif T.Common.Base_CPU /= System.Multiprocessors.Not_A_Specific_CPU then declare - CPU_Set : aliased cpu_set_t := (bits => (others => False)); + CPU_Set : aliased cpu_set_t; + begin - CPU_Set.bits (Integer (T.Common.Base_CPU)) := True; + System.OS_Interface.CPU_ZERO (CPU_Set'Access); + System.OS_Interface.CPU_SET + (int (T.Common.Base_CPU), CPU_Set'Access); Result := pthread_attr_setaffinity_np (Attributes'Access, @@ -905,14 +908,18 @@ Multiprocessors.Number_Of_CPUs => True)) then declare - CPU_Set : aliased cpu_set_t := (bits => (others => False)); + CPU_Set : aliased cpu_set_t; begin + System.OS_Interface.CPU_ZERO (CPU_Set'Access); + -- Set the affinity to all the processors belonging to the -- dispatching domain. for Proc in T.Common.Domain'Range loop - CPU_Set.bits (Integer (Proc)) := T.Common.Domain (Proc); + if T.Common.Domain (Proc) then + System.OS_Interface.CPU_SET (int (Proc), CPU_Set'Access); + end if; end loop; Result := @@ -1394,8 +1401,9 @@ 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; - CPU_Set : cpu_set_t_ptr := null; Result : Interfaces.C.int; begin @@ -1406,16 +1414,17 @@ 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); + System.OS_Interface.CPU_SET + (int (T.Common.Base_CPU), CPU_Set'Access); + CPU_Set_Ptr := CPU_Set'Access; - CPU_Set := new cpu_set_t'(bits => (others => False)); - CPU_Set.bits (Integer (T.Common.Base_CPU)) := True; - -- Handle Task_Info elsif T.Common.Task_Info /= null and then T.Common.Task_Info.CPU_Affinity /= Task_Info.Any_CPU then - CPU_Set := T.Common.Task_Info.CPU_Affinity'Access; + CPU_Set_Ptr := T.Common.Task_Info.CPU_Affinity'Access; -- Handle dispatching domains @@ -1431,11 +1440,13 @@ -- domain other than the default one, or when the default one -- has been modified. - CPU_Set := new cpu_set_t'(bits => (others => False)); + System.OS_Interface.CPU_ZERO (CPU_Set'Access); for Proc in T.Common.Domain'Range loop - CPU_Set.bits (Integer (Proc)) := T.Common.Domain (Proc); + System.OS_Interface.CPU_SET (int (Proc), CPU_Set'Access); end loop; + + CPU_Set_Ptr := CPU_Set'Access; end if; -- We set the new affinity if needed. Otherwise, the new task @@ -1443,10 +1454,10 @@ -- the documentation of pthread_setaffinity_np), which is -- consistent with Ada's required semantics. - if CPU_Set /= null then + if CPU_Set_Ptr /= null then Result := pthread_setaffinity_np - (T.Common.LL.Thread, CPU_SETSIZE / 8, CPU_Set); + (T.Common.LL.Thread, CPU_SETSIZE / 8, CPU_Set_Ptr); pragma Assert (Result = 0); end if; end; Index: adaint.c =================================================================== --- adaint.c (revision 178381) +++ adaint.c (working copy) @@ -3770,6 +3770,20 @@ { return (void *) syscall (__NR_gettid); } + +#include <sched.h> + +void __gnat_cpu_zero (cpu_set_t *set) +{ + CPU_ZERO (set); +} + +void __gnat_cpu_set (int cpu, 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); +} #endif #ifdef __cplusplus Index: adaint.h =================================================================== --- adaint.h (revision 178381) +++ adaint.h (working copy) @@ -247,6 +247,13 @@ int *, char *, int *); #if defined (linux) extern void *__gnat_lwp_self (void); + +/* Routines for interface to required CPU set primitives */ + +#include <sched.h> + +extern void __gnat_cpu_zero (cpu_set_t *); +extern void __gnat_cpu_set (int, cpu_set_t *); #endif #if defined (_WIN32)