diff options
author | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-02-25 15:59:05 +0000 |
---|---|---|
committer | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-02-25 15:59:05 +0000 |
commit | 632a89954bc74fcf3cbc4cd34d04da14093ea3a8 (patch) | |
tree | 55546168634e1653e8e637a0b8c0f34c3ccdada9 /gcc/ada/s-tpobop.adb | |
parent | fd11b6022fadd0ed9993f7bd3a8c8858f2be1ddd (diff) | |
download | gcc-632a89954bc74fcf3cbc4cd34d04da14093ea3a8.tar.gz |
2004-02-25 Robert Dewar <dewar@gnat.com>
* 51osinte.ads, 52osinte.ads, 53osinte.ads, 54osinte.ads,
55osinte.ads, 56osinte.ads, 5aosinte.ads, 5bosinte.ads,
5cosinte.ads, 5fosinte.ads, 5gosinte.ads, 5hosinte.ads,
5iosinte.ads, 5losinte.ads, 5nosinte.ads, 5oosinte.ads,
5posinte.ads, 5sosinte.ads, 5tosinte.ads, 5vosinte.ads,
5wosinte.ads, 5zosinte.ads: Move instances of Unchecked_Conversion to
the defining instance of the type to avoid aliasing problems.
Fix copyright header. Fix bad comments in package header.
* exp_util.adb, prj-part.adb, prj-part.adb: Minor reformatting
2004-02-25 Ed Schonberg <schonberg@gnat.com>
* exp_ch2.adb (Param_Entity): Handle properly formals that have been
rewritten as references when aliased through an address clause.
* sem_ch4.adb (Try_Indirect_Call): Normalize actuals before checking
whether call can be interpreted as an indirect call to the result of a
parameterless function call returning an access subprogram.
2004-02-25 Arnaud Charlet <charlet@act-europe.fr>
Code clean up:
* exp_ch7.adb (Make_Clean): Remove generation of calls to
Unlock[_Entries], since this is now done by Service_Entries directly.
* exp_ch9.adb (Build_Protected_Subprogram_Body): ditto.
* s-tpobop.ads, s-tpobop.adb (PO_Service_Entries): New nested procedure
Requeue_Call for better code readability. Change spec and update calls:
PO_Service_Entries now unlock the PO on exit.
(Protected_Entry_Call, Timed_Protected_Entry_Call): Update calls to
PO_Service_Entries.
* s-tposen.ads, s-tposen.adb (Service_Entry): Now unlock the PO on exit.
* s-taenca.adb, s-tasren.adb: Update calls to PO_Service_Entries.
2004-02-25 Sergey Rybin <rybin@act-europe.fr>
* exp_ch9.adb (Build_Simple_Entry_Call): Prevent expanding the
protected subprogram call and analyzing the result of such expanding
in case when the called protected subprogram is eliminated.
* sem_elim.adb (Check_Eliminated): Skip blocks when comparing scope
names.
2004-02-25 Jerome Guitton <guitton@act-europe.fr>
* Makefile.in: Clean ups.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@78436 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/s-tpobop.adb')
-rw-r--r-- | gcc/ada/s-tpobop.adb | 253 |
1 files changed, 133 insertions, 120 deletions
diff --git a/gcc/ada/s-tpobop.adb b/gcc/ada/s-tpobop.adb index 275f872de9a..cf15ed9f88a 100644 --- a/gcc/ada/s-tpobop.adb +++ b/gcc/ada/s-tpobop.adb @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 1998-2003, Free Software Foundation, Inc. -- +-- Copyright (C) 1998-2004, Free Software Foundation, Inc. -- -- -- -- GNARL 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- -- @@ -376,7 +376,6 @@ package body System.Tasking.Protected_Objects.Operations is else PO_Do_Or_Queue (Self_ID, New_Object, Entry_Call, With_Abort); PO_Service_Entries (Self_ID, New_Object); - Unlock_Entries (New_Object); end if; else @@ -441,150 +440,168 @@ package body System.Tasking.Protected_Objects.Operations is ------------------------ procedure PO_Service_Entries - (Self_ID : Task_ID; - Object : Protection_Entries_Access) + (Self_ID : Task_ID; + Object : Entries.Protection_Entries_Access; + Unlock_Object : Boolean := True) is - Entry_Call : Entry_Call_Link; - E : Protected_Entry_Index; - Caller : Task_ID; - New_Object : Protection_Entries_Access; - Ceiling_Violation : Boolean; - Result : Boolean; + procedure Requeue_Call + (Entry_Call : Entry_Call_Link; + Call_Cancelled : out Boolean); + -- Handle requeue of Entry_Call. + -- Call_Cancelled is set to True of call was cancelled. - begin - loop - Queuing.Select_Protected_Entry_Call (Self_ID, Object, Entry_Call); + ------------------ + -- Requeue_Call -- + ------------------ + + procedure Requeue_Call + (Entry_Call : Entry_Call_Link; + Call_Cancelled : out Boolean) + is + New_Object : Protection_Entries_Access; + Ceiling_Violation : Boolean; + Result : Boolean; + E : Protected_Entry_Index; + + begin + Call_Cancelled := False; + New_Object := To_Protection (Entry_Call.Called_PO); - if Entry_Call /= null then - E := Protected_Entry_Index (Entry_Call.E); + if New_Object = null then - -- Not abortable while service is in progress. + -- Call is to be requeued to a task entry - if Entry_Call.State = Now_Abortable then - Entry_Call.State := Was_Abortable; + if Single_Lock then + STPO.Lock_RTS; end if; - Object.Call_In_Progress := Entry_Call; + Result := Rendezvous.Task_Do_Or_Queue + (Self_ID, Entry_Call, + With_Abort => Entry_Call.Requeue_With_Abort); - begin - if Runtime_Traces then - Send_Trace_Info (PO_Run, Self_ID, - Entry_Call.Self, Entry_Index (E)); - end if; + if not Result then + Queuing.Broadcast_Program_Error + (Self_ID, Object, Entry_Call, RTS_Locked => True); + end if; + + if Single_Lock then + STPO.Unlock_RTS; + end if; + + else + -- Call should be requeued to a PO + + if Object /= New_Object then - pragma Debug - (Debug.Trace (Self_ID, "POSE: start entry body", 'P')); - Object.Entry_Bodies ( - Object.Find_Body_Index (Object.Compiler_Info, E)).Action ( - Object.Compiler_Info, Entry_Call.Uninterpreted_Data, E); - exception - when others => + -- Requeue is to different PO + + Lock_Entries (New_Object, Ceiling_Violation); + + if Ceiling_Violation then + Object.Call_In_Progress := null; Queuing.Broadcast_Program_Error (Self_ID, Object, Entry_Call); - end; - if Object.Call_In_Progress /= null then - Object.Call_In_Progress := null; - Caller := Entry_Call.Self; - - if Single_Lock then - STPO.Lock_RTS; + else + PO_Do_Or_Queue (Self_ID, New_Object, Entry_Call, + Entry_Call.Requeue_With_Abort); + PO_Service_Entries (Self_ID, New_Object); end if; - STPO.Write_Lock (Caller); - Initialization.Wakeup_Entry_Caller (Self_ID, Entry_Call, Done); - STPO.Unlock (Caller); + else + -- Requeue is to same protected object - if Single_Lock then - STPO.Unlock_RTS; + if Entry_Call.Requeue_With_Abort + and then Entry_Call.Cancellation_Attempted + then + -- If this is a requeue with abort and someone tried + -- to cancel this call, cancel it at this point. + + Entry_Call.State := Cancelled; + Call_Cancelled := True; + return; end if; - else - -- Call needs to be requeued + if not Entry_Call.Requeue_With_Abort or else + Entry_Call.Mode /= Conditional_Call + then + E := Protected_Entry_Index (Entry_Call.E); + Queuing.Enqueue + (New_Object.Entry_Queues (E), Entry_Call); + Update_For_Queue_To_PO (Entry_Call, + Entry_Call.Requeue_With_Abort); + + else + PO_Do_Or_Queue (Self_ID, New_Object, Entry_Call, + Entry_Call.Requeue_With_Abort); + end if; + end if; + end if; + end Requeue_Call; - New_Object := To_Protection (Entry_Call.Called_PO); + E : Protected_Entry_Index; + Caller : Task_ID; + Entry_Call : Entry_Call_Link; + Cancelled : Boolean; - if New_Object = null then + begin + loop + Queuing.Select_Protected_Entry_Call (Self_ID, Object, Entry_Call); - -- Call is to be requeued to a task entry + exit when Entry_Call = null; - if Single_Lock then - STPO.Lock_RTS; - end if; + E := Protected_Entry_Index (Entry_Call.E); - Result := Rendezvous.Task_Do_Or_Queue - (Self_ID, Entry_Call, - With_Abort => Entry_Call.Requeue_With_Abort); + -- Not abortable while service is in progress. - if not Result then - Queuing.Broadcast_Program_Error - (Self_ID, Object, Entry_Call, RTS_Locked => True); - end if; + if Entry_Call.State = Now_Abortable then + Entry_Call.State := Was_Abortable; + end if; - if Single_Lock then - STPO.Unlock_RTS; - end if; + Object.Call_In_Progress := Entry_Call; - else - -- Call should be requeued to a PO - - if Object /= New_Object then - -- Requeue is to different PO - - Lock_Entries (New_Object, Ceiling_Violation); - - if Ceiling_Violation then - Object.Call_In_Progress := null; - Queuing.Broadcast_Program_Error - (Self_ID, Object, Entry_Call); - - else - PO_Do_Or_Queue (Self_ID, New_Object, Entry_Call, - Entry_Call.Requeue_With_Abort); - PO_Service_Entries (Self_ID, New_Object); - Unlock_Entries (New_Object); - end if; - - else - -- Requeue is to same protected object - - -- ??? Try to compensate apparent failure of the - -- scheduler on some OS (e.g VxWorks) to give higher - -- priority tasks a chance to run (see CXD6002). - - STPO.Yield (False); - - if Entry_Call.Requeue_With_Abort - and then Entry_Call.Cancellation_Attempted - then - -- If this is a requeue with abort and someone tried - -- to cancel this call, cancel it at this point. - - Entry_Call.State := Cancelled; - exit; - end if; - - if not Entry_Call.Requeue_With_Abort or else - Entry_Call.Mode /= Conditional_Call - then - E := Protected_Entry_Index (Entry_Call.E); - Queuing.Enqueue - (New_Object.Entry_Queues (E), Entry_Call); - Update_For_Queue_To_PO (Entry_Call, - Entry_Call.Requeue_With_Abort); - - else - PO_Do_Or_Queue (Self_ID, New_Object, Entry_Call, - Entry_Call.Requeue_With_Abort); - end if; - end if; - end if; + begin + if Runtime_Traces then + Send_Trace_Info (PO_Run, Self_ID, + Entry_Call.Self, Entry_Index (E)); end if; + pragma Debug + (Debug.Trace (Self_ID, "POSE: start entry body", 'P')); + Object.Entry_Bodies ( + Object.Find_Body_Index (Object.Compiler_Info, E)).Action ( + Object.Compiler_Info, Entry_Call.Uninterpreted_Data, E); + exception + when others => + Queuing.Broadcast_Program_Error + (Self_ID, Object, Entry_Call); + end; + + if Object.Call_In_Progress = null then + Requeue_Call (Entry_Call, Cancelled); + exit when Cancelled; + else - exit; + Object.Call_In_Progress := null; + Caller := Entry_Call.Self; + + if Single_Lock then + STPO.Lock_RTS; + end if; + + STPO.Write_Lock (Caller); + Initialization.Wakeup_Entry_Caller (Self_ID, Entry_Call, Done); + STPO.Unlock (Caller); + + if Single_Lock then + STPO.Unlock_RTS; + end if; end if; end loop; + + if Unlock_Object then + Unlock_Entries (Object); + end if; end PO_Service_Entries; --------------------- @@ -712,8 +729,6 @@ package body System.Tasking.Protected_Objects.Operations is Initially_Abortable := Entry_Call.State = Now_Abortable; PO_Service_Entries (Self_ID, Object); - Unlock_Entries (Object); - -- Try to prevent waiting later (in Cancel_Protected_Entry_Call) -- for completed or cancelled calls. (This is a heuristic, only.) @@ -971,8 +986,6 @@ package body System.Tasking.Protected_Objects.Operations is PO_Do_Or_Queue (Self_Id, Object, Entry_Call, With_Abort => True); PO_Service_Entries (Self_Id, Object); - Unlock_Entries (Object); - -- Try to avoid waiting for completed or cancelled calls. if Entry_Call.State >= Done then |