diff options
author | Arnaud Charlet <charlet@gcc.gnu.org> | 2010-10-18 12:27:48 +0200 |
---|---|---|
committer | Arnaud Charlet <charlet@gcc.gnu.org> | 2010-10-18 12:27:48 +0200 |
commit | 8918fe18ab24b24cba7575face37f1726a23ef19 (patch) | |
tree | 857aedf3baf2b3a0ed2ad1c3eaef04565c4b834b /gcc/ada/s-taprop-linux.adb | |
parent | e57ab5507b20632ae70b0ce192cbeca049133a1a (diff) | |
download | gcc-8918fe18ab24b24cba7575face37f1726a23ef19.zip gcc-8918fe18ab24b24cba7575face37f1726a23ef19.tar.gz gcc-8918fe18ab24b24cba7575face37f1726a23ef19.tar.bz2 |
[multiple changes]
2010-10-18 Jose Ruiz <ruiz@adacore.com>
* exp_ch9.adb (Expand_N_Task_Type_Declaration): Add field corresponding
to the affinity when expanding the task declaration.
(Make_Task_Create_Call): Add the affinity parameter to the call to
create task.
* sem_prag.adb (Analyze_Pragma): Add the analysis for pragma CPU,
taking into account the case when it applies to a subprogram (only for
main and with static expression) or to a task.
* par_prag.adb:(Prag): Make pragma CPU a valid one.
* snames.ads-tmpl (Name_uCPU, Name_CPU): Add these new name identifiers
used by the expander for handling the affinity parameter when creating
a task.
(Pragma_Id): Add Pragma_CPU as a valid one.
* rtsfind.ads (RTU_Id): Make System_Multiprocessors accesible.
(RE_Id, RE_Unit_Table): Make the entities RE_CPU_Range and
RE_Unspecified_CPU visible.
* sinfo.ads, sinfo.adb (Has_Pragma_CPU, Set_Has_Pragma_CPU): Add these
two subprograms to set/get the flag indicating whether there is a
pragma CPU which applies to the entity.
* lib.ads, lib.adb (Unit_Record, Default_Main_CPU, Main_CPU,
Set_Main_CPU): Add the field Main_CPU to Unit_Record to store the value
of the affinity associated to the main subprogram (if any).
Default_Main_CPU is used when no affinity is set. Subprograms
Set_Main_CPU and Main_CPU are added to set/get the affinity of the main
subprogram.
* ali.ads, ali.adb (ALIs_Record): Add field Main_CPU to contain the
value of the affinity of the main subprogram.
(Scan_ALI): Get the affinity of the main subprogram (encoded as C=XX in
the M line).
* lib-writ.ads, lib-writ.adb (M_Parameters): Encode the affinity of the
main subprogram in the M (main) line using C=XX.
* lib-load.adb (Create_Dummy_Package_Unit, Load_Main_Source,
Load_Unit): Add new field Main_CPU.
* bindgen.adb (Gen_Adainit_Ada, Gen_Adainit_C): Add the code to pass
the affinity of the main subprogram to the run time.
* s-taskin.ads (Common_ATCB): Add the field Base_CPU to store the
affinity.
(Unspecified_CPU): Add this constant to identify the case when no
affinity is set for tasks.
* s-taskin.adb (Initialize_ATCB): Store the value coming from pragma
CPU in the common part of the ATCB.
(Initialize): Store the value coming from pragma CPU (for the
environment task) in the common part of the ATCB.
* s-tassta.ads, s-tassta.adb (Create_Task): Add the affinity specified
by pragma CPU to the ATCB.
* s-tarest.ads, s-tarest.adb (Create_Restricted_Task): Add the affinity
specified by pragma CPU to the ATCB.
* s-tporft.adb (Register_Foreign_Thread): Add the new affinity
parameter to the call to Initialize_ATCB.
* s-taprop-linux.adb (Create_Task): Change the attributes of the thread
to include the task affinity before creation. Additionally, the
affinity selected with Task_Info is also enforced changing the
attributes at task creation time, instead of changing it after creation.
(Initialize): Change the affinity of the environment task if required
by a pragma CPU.
* s-osinte-linux.ads (pthread_setaffinity_np): Instead of using a
wrapper to check whether the function is available or not, use a weak
symbol.
(pthread_attr_setaffinity_np): Add the import of this function which is
used to change the affinity in the attributes used to create a thread.
* adaint.c (__gnat_pthread_attr_setaffinity_np): Remove this wrapper.
It was used to check whether the pthread function was available or not,
but the use of a weak symbol handles this situation in a cleaner way.
* s-taprop-mingw.adb (Create_Task, Initialize): Change the affinity of
tasks (including the environment task) if required by a pragma CPU.
* s-taprop-solaris.adb (Enter_Task): Change the affinity of tasks
(including the environment task) if required by a pragma CPU.
* s-taprop-vxworks.adb (Create_Task, Initialize): Change the affinity
of tasks (including the environment task) if required by a pragma CPU.
* init.c (__gl_main_cpu): Make this value visible to the run time. It
will pass the affinity of the environment task.
2010-10-18 Javier Miranda <miranda@adacore.com>
* einfo.adb (Direct_Primitive_Operations): Complete assertion.
From-SVN: r165625
Diffstat (limited to 'gcc/ada/s-taprop-linux.adb')
-rw-r--r-- | gcc/ada/s-taprop-linux.adb | 80 |
1 files changed, 67 insertions, 13 deletions
diff --git a/gcc/ada/s-taprop-linux.adb b/gcc/ada/s-taprop-linux.adb index 38b4cf6..f19ca55 100644 --- a/gcc/ada/s-taprop-linux.adb +++ b/gcc/ada/s-taprop-linux.adb @@ -48,6 +48,7 @@ with System.Tasking.Debug; with System.Interrupt_Management; with System.OS_Primitives; with System.Stack_Checking.Operations; +with System.Multiprocessors; with System.Soft_Links; -- We use System.Soft_Links instead of System.Tasking.Initialization @@ -819,6 +820,8 @@ package body System.Task_Primitives.Operations is Adjusted_Stack_Size : Interfaces.C.size_t; Result : Interfaces.C.int; + use type System.Multiprocessors.CPU_Range; + begin Adjusted_Stack_Size := Interfaces.C.size_t (Stack_Size + Alternate_Stack_Size); @@ -841,6 +844,48 @@ package body System.Task_Primitives.Operations is (Attributes'Access, PTHREAD_CREATE_DETACHED); pragma Assert (Result = 0); + -- We were calling pthread_setaffinity_np (after thread creation but + -- before thread activation) to set the affinity but it was not + -- behaving as expected. Now we set the required attributes for the + -- creation of the thread, which is working correctly and it is + -- more appropriate. + + if pthread_attr_setaffinity_np'Address = System.Null_Address then + -- Nothing to do with the affinities if there is not the underlying + -- support. + + null; + + -- Handle pragma CPU + + elsif T.Common.Base_CPU /= System.Multiprocessors.Not_A_Specific_CPU then + declare + CPU_Set : aliased cpu_set_t := (bits => (others => False)); + + begin + CPU_Set.bits (Integer (T.Common.Base_CPU)) := True; + + Result := + pthread_attr_setaffinity_np + (Attributes'Access, + CPU_SETSIZE / 8, + CPU_Set'Access); + pragma Assert (Result = 0); + end; + + -- Handle Task_Info + + elsif T.Common.Task_Info /= null + and then T.Common.Task_Info.CPU_Affinity /= Task_Info.Any_CPU + then + Result := + pthread_attr_setaffinity_np + (Attributes'Access, + CPU_SETSIZE / 8, + T.Common.Task_Info.CPU_Affinity'Access); + pragma Assert (Result = 0); + end if; + -- Since the initial signal mask of a thread is inherited from the -- creator, and the Environment task has all its signals masked, we -- do not need to manipulate caller's signal mask at this point. @@ -863,19 +908,6 @@ package body System.Task_Primitives.Operations is Succeeded := True; - -- Handle Task_Info - - if T.Common.Task_Info /= null then - if T.Common.Task_Info.CPU_Affinity /= Task_Info.Any_CPU then - Result := - pthread_setaffinity_np - (T.Common.LL.Thread, - CPU_SETSIZE / 8, - T.Common.Task_Info.CPU_Affinity'Access); - pragma Assert (Result = 0); - end if; - end if; - Result := pthread_attr_destroy (Attributes'Access); pragma Assert (Result = 0); @@ -1238,6 +1270,8 @@ package body System.Task_Primitives.Operations is -- 's' Interrupt_State pragma set state to System (use "default" -- system handler) + use type System.Multiprocessors.CPU_Range; + begin Environment_Task_Id := Environment_Task; @@ -1298,6 +1332,26 @@ package body System.Task_Primitives.Operations is pragma Assert (Result = 0); Abort_Handler_Installed := True; end if; + + -- pragma CPU for the environment task + + if Environment_Task.Common.Base_CPU /= + System.Multiprocessors.Not_A_Specific_CPU + then + declare + CPU_Set : aliased cpu_set_t := (bits => (others => False)); + + begin + CPU_Set.bits (Integer (Environment_Task.Common.Base_CPU)) := True; + + Result := + pthread_setaffinity_np + (Environment_Task.Common.LL.Thread, + CPU_SETSIZE / 8, + CPU_Set'Access); + pragma Assert (Result = 0); + end; + end if; end Initialize; end System.Task_Primitives.Operations; |