summaryrefslogtreecommitdiff
path: root/gcc/ada/s-tpobop.adb
diff options
context:
space:
mode:
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2004-02-25 15:59:05 +0000
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2004-02-25 15:59:05 +0000
commit632a89954bc74fcf3cbc4cd34d04da14093ea3a8 (patch)
tree55546168634e1653e8e637a0b8c0f34c3ccdada9 /gcc/ada/s-tpobop.adb
parentfd11b6022fadd0ed9993f7bd3a8c8858f2be1ddd (diff)
downloadgcc-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.adb253
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