aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.4.3/gcc/ada/s-tasque.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.4.3/gcc/ada/s-tasque.adb')
-rw-r--r--gcc-4.4.3/gcc/ada/s-tasque.adb625
1 files changed, 0 insertions, 625 deletions
diff --git a/gcc-4.4.3/gcc/ada/s-tasque.adb b/gcc-4.4.3/gcc/ada/s-tasque.adb
deleted file mode 100644
index 5116c88c0..000000000
--- a/gcc-4.4.3/gcc/ada/s-tasque.adb
+++ /dev/null
@@ -1,625 +0,0 @@
-------------------------------------------------------------------------------
--- --
--- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS --
--- --
--- S Y S T E M . T A S K I N G . Q U E U I N G --
--- --
--- B o d y --
--- --
--- Copyright (C) 1992-2009, 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- --
--- ware Foundation; either version 3, or (at your option) any later ver- --
--- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
--- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
--- or FITNESS FOR A PARTICULAR PURPOSE. --
--- --
--- As a special exception under Section 7 of GPL version 3, you are granted --
--- additional permissions described in the GCC Runtime Library Exception, --
--- version 3.1, as published by the Free Software Foundation. --
--- --
--- You should have received a copy of the GNU General Public License and --
--- a copy of the GCC Runtime Library Exception along with this program; --
--- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
--- <http://www.gnu.org/licenses/>. --
--- --
--- GNARL was developed by the GNARL team at Florida State University. --
--- Extensive contributions were provided by Ada Core Technologies, Inc. --
--- --
-------------------------------------------------------------------------------
-
--- This version of the body implements queueing policy according to the policy
--- specified by the pragma Queuing_Policy. When no such pragma is specified
--- FIFO policy is used as default.
-
-with System.Task_Primitives.Operations;
-with System.Tasking.Initialization;
-with System.Parameters;
-
-package body System.Tasking.Queuing is
-
- use Parameters;
- use Task_Primitives.Operations;
- use Protected_Objects;
- use Protected_Objects.Entries;
-
- -- Entry Queues implemented as doubly linked list
-
- Queuing_Policy : Character;
- pragma Import (C, Queuing_Policy, "__gl_queuing_policy");
-
- Priority_Queuing : constant Boolean := Queuing_Policy = 'P';
-
- procedure Send_Program_Error
- (Self_ID : Task_Id;
- Entry_Call : Entry_Call_Link);
- -- Raise Program_Error in the caller of the specified entry call
-
- function Check_Queue (E : Entry_Queue) return Boolean;
- -- Check the validity of E.
- -- Return True if E is valid, raise Assert_Failure if assertions are
- -- enabled and False otherwise.
-
- -----------------------------
- -- Broadcast_Program_Error --
- -----------------------------
-
- procedure Broadcast_Program_Error
- (Self_ID : Task_Id;
- Object : Protection_Entries_Access;
- Pending_Call : Entry_Call_Link;
- RTS_Locked : Boolean := False)
- is
- Entry_Call : Entry_Call_Link;
- begin
- if Single_Lock and then not RTS_Locked then
- Lock_RTS;
- end if;
-
- if Pending_Call /= null then
- Send_Program_Error (Self_ID, Pending_Call);
- end if;
-
- for E in Object.Entry_Queues'Range loop
- Dequeue_Head (Object.Entry_Queues (E), Entry_Call);
-
- while Entry_Call /= null loop
- pragma Assert (Entry_Call.Mode /= Conditional_Call);
-
- Send_Program_Error (Self_ID, Entry_Call);
- Dequeue_Head (Object.Entry_Queues (E), Entry_Call);
- end loop;
- end loop;
-
- if Single_Lock and then not RTS_Locked then
- Unlock_RTS;
- end if;
- end Broadcast_Program_Error;
-
- -----------------
- -- Check_Queue --
- -----------------
-
- function Check_Queue (E : Entry_Queue) return Boolean is
- Valid : Boolean := True;
- C, Prev : Entry_Call_Link;
-
- begin
- if E.Head = null then
- if E.Tail /= null then
- Valid := False;
- pragma Assert (Valid);
- end if;
- else
- if E.Tail = null
- or else E.Tail.Next /= E.Head
- then
- Valid := False;
- pragma Assert (Valid);
-
- else
- C := E.Head;
-
- loop
- Prev := C;
- C := C.Next;
-
- if C = null then
- Valid := False;
- pragma Assert (Valid);
- exit;
- end if;
-
- if Prev /= C.Prev then
- Valid := False;
- pragma Assert (Valid);
- exit;
- end if;
-
- exit when C = E.Head;
- end loop;
-
- if Prev /= E.Tail then
- Valid := False;
- pragma Assert (Valid);
- end if;
- end if;
- end if;
-
- return Valid;
- end Check_Queue;
-
- -------------------
- -- Count_Waiting --
- -------------------
-
- -- Return number of calls on the waiting queue of E
-
- function Count_Waiting (E : Entry_Queue) return Natural is
- Count : Natural;
- Temp : Entry_Call_Link;
-
- begin
- pragma Assert (Check_Queue (E));
-
- Count := 0;
-
- if E.Head /= null then
- Temp := E.Head;
-
- loop
- Count := Count + 1;
- exit when E.Tail = Temp;
- Temp := Temp.Next;
- end loop;
- end if;
-
- return Count;
- end Count_Waiting;
-
- -------------
- -- Dequeue --
- -------------
-
- -- Dequeue call from entry_queue E
-
- procedure Dequeue (E : in out Entry_Queue; Call : Entry_Call_Link) is
- begin
- pragma Assert (Check_Queue (E));
- pragma Assert (Call /= null);
-
- -- If empty queue, simply return
-
- if E.Head = null then
- return;
- end if;
-
- pragma Assert (Call.Prev /= null);
- pragma Assert (Call.Next /= null);
-
- Call.Prev.Next := Call.Next;
- Call.Next.Prev := Call.Prev;
-
- if E.Head = Call then
-
- -- Case of one element
-
- if E.Tail = Call then
- E.Head := null;
- E.Tail := null;
-
- -- More than one element
-
- else
- E.Head := Call.Next;
- end if;
-
- elsif E.Tail = Call then
- E.Tail := Call.Prev;
- end if;
-
- -- Successfully dequeued
-
- Call.Prev := null;
- Call.Next := null;
- pragma Assert (Check_Queue (E));
- end Dequeue;
-
- ------------------
- -- Dequeue_Call --
- ------------------
-
- procedure Dequeue_Call (Entry_Call : Entry_Call_Link) is
- Called_PO : Protection_Entries_Access;
-
- begin
- pragma Assert (Entry_Call /= null);
-
- if Entry_Call.Called_Task /= null then
- Dequeue
- (Entry_Call.Called_Task.Entry_Queues
- (Task_Entry_Index (Entry_Call.E)),
- Entry_Call);
-
- else
- Called_PO := To_Protection (Entry_Call.Called_PO);
- Dequeue (Called_PO.Entry_Queues
- (Protected_Entry_Index (Entry_Call.E)),
- Entry_Call);
- end if;
- end Dequeue_Call;
-
- ------------------
- -- Dequeue_Head --
- ------------------
-
- -- Remove and return the head of entry_queue E
-
- procedure Dequeue_Head
- (E : in out Entry_Queue;
- Call : out Entry_Call_Link)
- is
- Temp : Entry_Call_Link;
-
- begin
- pragma Assert (Check_Queue (E));
- -- If empty queue, return null pointer
-
- if E.Head = null then
- Call := null;
- return;
- end if;
-
- Temp := E.Head;
-
- -- Case of one element
-
- if E.Head = E.Tail then
- E.Head := null;
- E.Tail := null;
-
- -- More than one element
-
- else
- pragma Assert (Temp /= null);
- pragma Assert (Temp.Next /= null);
- pragma Assert (Temp.Prev /= null);
-
- E.Head := Temp.Next;
- Temp.Prev.Next := Temp.Next;
- Temp.Next.Prev := Temp.Prev;
- end if;
-
- -- Successfully dequeued
-
- Temp.Prev := null;
- Temp.Next := null;
- Call := Temp;
- pragma Assert (Check_Queue (E));
- end Dequeue_Head;
-
- -------------
- -- Enqueue --
- -------------
-
- -- Enqueue call at the end of entry_queue E, for FIFO queuing policy.
- -- Enqueue call priority ordered, FIFO at same priority level, for
- -- Priority queuing policy.
-
- procedure Enqueue (E : in out Entry_Queue; Call : Entry_Call_Link) is
- Temp : Entry_Call_Link := E.Head;
-
- begin
- pragma Assert (Check_Queue (E));
- pragma Assert (Call /= null);
-
- -- Priority Queuing
-
- if Priority_Queuing then
- if Temp = null then
- Call.Prev := Call;
- Call.Next := Call;
- E.Head := Call;
- E.Tail := Call;
-
- else
- loop
- -- Find the entry that the new guy should precede
-
- exit when Call.Prio > Temp.Prio;
- Temp := Temp.Next;
-
- if Temp = E.Head then
- Temp := null;
- exit;
- end if;
- end loop;
-
- if Temp = null then
- -- Insert at tail
-
- Call.Prev := E.Tail;
- Call.Next := E.Head;
- E.Tail := Call;
-
- else
- Call.Prev := Temp.Prev;
- Call.Next := Temp;
-
- -- Insert at head
-
- if Temp = E.Head then
- E.Head := Call;
- end if;
- end if;
-
- pragma Assert (Call.Prev /= null);
- pragma Assert (Call.Next /= null);
-
- Call.Prev.Next := Call;
- Call.Next.Prev := Call;
- end if;
-
- pragma Assert (Check_Queue (E));
- return;
- end if;
-
- -- FIFO Queuing
-
- if E.Head = null then
- E.Head := Call;
- else
- E.Tail.Next := Call;
- Call.Prev := E.Tail;
- end if;
-
- E.Head.Prev := Call;
- E.Tail := Call;
- Call.Next := E.Head;
- pragma Assert (Check_Queue (E));
- end Enqueue;
-
- ------------------
- -- Enqueue_Call --
- ------------------
-
- procedure Enqueue_Call (Entry_Call : Entry_Call_Link) is
- Called_PO : Protection_Entries_Access;
-
- begin
- pragma Assert (Entry_Call /= null);
-
- if Entry_Call.Called_Task /= null then
- Enqueue
- (Entry_Call.Called_Task.Entry_Queues
- (Task_Entry_Index (Entry_Call.E)),
- Entry_Call);
-
- else
- Called_PO := To_Protection (Entry_Call.Called_PO);
- Enqueue (Called_PO.Entry_Queues
- (Protected_Entry_Index (Entry_Call.E)),
- Entry_Call);
- end if;
- end Enqueue_Call;
-
- ----------
- -- Head --
- ----------
-
- -- Return the head of entry_queue E
-
- function Head (E : Entry_Queue) return Entry_Call_Link is
- begin
- pragma Assert (Check_Queue (E));
- return E.Head;
- end Head;
-
- -------------
- -- Onqueue --
- -------------
-
- -- Return True if Call is on any entry_queue at all
-
- function Onqueue (Call : Entry_Call_Link) return Boolean is
- begin
- pragma Assert (Call /= null);
-
- -- Utilize the fact that every queue is circular, so if Call
- -- is on any queue at all, Call.Next must NOT be null.
-
- return Call.Next /= null;
- end Onqueue;
-
- --------------------------------
- -- Requeue_Call_With_New_Prio --
- --------------------------------
-
- procedure Requeue_Call_With_New_Prio
- (Entry_Call : Entry_Call_Link; Prio : System.Any_Priority) is
- begin
- pragma Assert (Entry_Call /= null);
-
- -- Perform a queue reordering only when the policy being used is the
- -- Priority Queuing.
-
- if Priority_Queuing then
- if Onqueue (Entry_Call) then
- Dequeue_Call (Entry_Call);
- Entry_Call.Prio := Prio;
- Enqueue_Call (Entry_Call);
- end if;
- end if;
- end Requeue_Call_With_New_Prio;
-
- ---------------------------------
- -- Select_Protected_Entry_Call --
- ---------------------------------
-
- -- Select an entry of a protected object. Selection depends on the
- -- queuing policy being used.
-
- procedure Select_Protected_Entry_Call
- (Self_ID : Task_Id;
- Object : Protection_Entries_Access;
- Call : out Entry_Call_Link)
- is
- Entry_Call : Entry_Call_Link;
- Temp_Call : Entry_Call_Link;
- Entry_Index : Protected_Entry_Index := Null_Entry; -- stop warning
-
- begin
- Entry_Call := null;
-
- begin
- -- Priority queuing case
-
- if Priority_Queuing then
- for J in Object.Entry_Queues'Range loop
- Temp_Call := Head (Object.Entry_Queues (J));
-
- if Temp_Call /= null
- and then
- Object.Entry_Bodies
- (Object.Find_Body_Index
- (Object.Compiler_Info, J)).
- Barrier (Object.Compiler_Info, J)
- then
- if Entry_Call = null
- or else Entry_Call.Prio < Temp_Call.Prio
- then
- Entry_Call := Temp_Call;
- Entry_Index := J;
- end if;
- end if;
- end loop;
-
- -- FIFO queueing case
-
- else
- for J in Object.Entry_Queues'Range loop
- Temp_Call := Head (Object.Entry_Queues (J));
-
- if Temp_Call /= null
- and then
- Object.Entry_Bodies
- (Object.Find_Body_Index
- (Object.Compiler_Info, J)).
- Barrier (Object.Compiler_Info, J)
- then
- Entry_Call := Temp_Call;
- Entry_Index := J;
- exit;
- end if;
- end loop;
- end if;
-
- exception
- when others =>
- Broadcast_Program_Error (Self_ID, Object, null);
- end;
-
- -- If a call was selected, dequeue it and return it for service
-
- if Entry_Call /= null then
- Temp_Call := Entry_Call;
- Dequeue_Head (Object.Entry_Queues (Entry_Index), Entry_Call);
- pragma Assert (Temp_Call = Entry_Call);
- end if;
-
- Call := Entry_Call;
- end Select_Protected_Entry_Call;
-
- ----------------------------
- -- Select_Task_Entry_Call --
- ----------------------------
-
- -- Select an entry for rendezvous. Selection depends on the queuing policy
- -- being used.
-
- procedure Select_Task_Entry_Call
- (Acceptor : Task_Id;
- Open_Accepts : Accept_List_Access;
- Call : out Entry_Call_Link;
- Selection : out Select_Index;
- Open_Alternative : out Boolean)
- is
- Entry_Call : Entry_Call_Link;
- Temp_Call : Entry_Call_Link;
- Entry_Index : Task_Entry_Index := Task_Entry_Index'First;
- Temp_Entry : Task_Entry_Index;
-
- begin
- Open_Alternative := False;
- Entry_Call := null;
- Selection := No_Rendezvous;
-
- if Priority_Queuing then
- -- Priority queueing case
-
- for J in Open_Accepts'Range loop
- Temp_Entry := Open_Accepts (J).S;
-
- if Temp_Entry /= Null_Task_Entry then
- Open_Alternative := True;
- Temp_Call := Head (Acceptor.Entry_Queues (Temp_Entry));
-
- if Temp_Call /= null
- and then (Entry_Call = null
- or else Entry_Call.Prio < Temp_Call.Prio)
- then
- Entry_Call := Head (Acceptor.Entry_Queues (Temp_Entry));
- Entry_Index := Temp_Entry;
- Selection := J;
- end if;
- end if;
- end loop;
-
- else
- -- FIFO Queuing case
-
- for J in Open_Accepts'Range loop
- Temp_Entry := Open_Accepts (J).S;
-
- if Temp_Entry /= Null_Task_Entry then
- Open_Alternative := True;
- Temp_Call := Head (Acceptor.Entry_Queues (Temp_Entry));
-
- if Temp_Call /= null then
- Entry_Call := Head (Acceptor.Entry_Queues (Temp_Entry));
- Entry_Index := Temp_Entry;
- Selection := J;
- exit;
- end if;
- end if;
- end loop;
- end if;
-
- if Entry_Call /= null then
- Dequeue_Head (Acceptor.Entry_Queues (Entry_Index), Entry_Call);
-
- -- Guard is open
- end if;
-
- Call := Entry_Call;
- end Select_Task_Entry_Call;
-
- ------------------------
- -- Send_Program_Error --
- ------------------------
-
- procedure Send_Program_Error
- (Self_ID : Task_Id;
- Entry_Call : Entry_Call_Link)
- is
- Caller : Task_Id;
- begin
- Caller := Entry_Call.Self;
- Entry_Call.Exception_To_Raise := Program_Error'Identity;
- Write_Lock (Caller);
- Initialization.Wakeup_Entry_Caller (Self_ID, Entry_Call, Done);
- Unlock (Caller);
- end Send_Program_Error;
-
-end System.Tasking.Queuing;