-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2005, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2007, 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- --
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
-- for more details. You should have received a copy of the GNU General --
-- Public License distributed with GNARL; see file COPYING. If not, write --
--- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
--- MA 02111-1307, USA. --
+-- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
+-- Boston, MA 02110-1301, USA. --
-- --
-- As a special exception, if other files instantiate generics from this --
-- unit, or you link this unit with other files to produce an executable, --
-- used for Thread_Id
package System.Task_Primitives.Operations is
+ pragma Preelaborate;
- pragma Elaborate_Body;
package ST renames System.Tasking;
package OSI renames System.OS_Interface;
-- call specified below. See locking rules in System.Tasking (spec) for
-- more details.
- procedure Initialize_Lock (Prio : System.Any_Priority; L : access Lock);
- procedure Initialize_Lock (L : access RTS_Lock; Level : Lock_Level);
+ procedure Initialize_Lock
+ (Prio : System.Any_Priority;
+ L : not null access Lock);
+ procedure Initialize_Lock
+ (L : not null access RTS_Lock;
+ Level : Lock_Level);
pragma Inline (Initialize_Lock);
- -- Initialize a lock object.
+ -- Initialize a lock object
--
-- For Lock, Prio is the ceiling priority associated with the lock. For
-- RTS_Lock, the ceiling is implicitly Priority'Last.
-- unless the lock object has been initialized and has not since been
-- finalized.
--
- -- Initialization of the per-task lock is implicit in Create_Task.
+ -- Initialization of the per-task lock is implicit in Create_Task
--
- -- These operations raise Storage_Error if a lack of storage is detected.
+ -- These operations raise Storage_Error if a lack of storage is detected
- procedure Finalize_Lock (L : access Lock);
- procedure Finalize_Lock (L : access RTS_Lock);
+ procedure Finalize_Lock (L : not null access Lock);
+ procedure Finalize_Lock (L : not null access RTS_Lock);
pragma Inline (Finalize_Lock);
-- Finalize a lock object, freeing any resources allocated by the
-- corresponding Initialize_Lock operation.
- procedure Write_Lock (L : access Lock; Ceiling_Violation : out Boolean);
- procedure Write_Lock (L : access RTS_Lock; Global_Lock : Boolean := False);
- procedure Write_Lock (T : ST.Task_Id);
+ procedure Write_Lock
+ (L : not null access Lock;
+ Ceiling_Violation : out Boolean);
+ procedure Write_Lock
+ (L : not null access RTS_Lock;
+ Global_Lock : Boolean := False);
+ procedure Write_Lock
+ (T : ST.Task_Id);
pragma Inline (Write_Lock);
-- Lock a lock object for write access. After this operation returns,
-- the calling task holds write permission for the lock object. No other
-- holds T's lock, or has interrupt-level priority. Finalization of the
-- per-task lock is implicit in Exit_Task.
- procedure Read_Lock (L : access Lock; Ceiling_Violation : out Boolean);
+ procedure Read_Lock
+ (L : not null access Lock;
+ Ceiling_Violation : out Boolean);
pragma Inline (Read_Lock);
-- Lock a lock object for read access. After this operation returns,
-- the calling task has non-exclusive read permission for the logical
-- potential write access, and (3) implementations of priority ceiling
-- locking that make a reader-writer distinction have higher overhead.
- procedure Unlock (L : access Lock);
- procedure Unlock (L : access RTS_Lock; Global_Lock : Boolean := False);
- procedure Unlock (T : ST.Task_Id);
+ procedure Unlock
+ (L : not null access Lock);
+ procedure Unlock
+ (L : not null access RTS_Lock;
+ Global_Lock : Boolean := False);
+ procedure Unlock
+ (T : ST.Task_Id);
pragma Inline (Unlock);
- -- Unlock a locked lock object.
+ -- Unlock a locked lock object
--
-- The effect is undefined unless the calling task holds read or write
-- permission for the lock L, and L is the lock object most recently
-- done at interrupt priority. In general, it is not acceptable to give
-- all RTS locks interrupt priority, since that whould give terrible
-- performance on systems where this has the effect of masking hardware
- -- interrupts, though we could get away with allowing
- -- Interrupt_Priority'last where we are layered on an OS that does not
- -- allow us to mask interrupts. Ideally, we would like to raise
- -- Program_Error back at the original point of the RTS call, but this
- -- would require a lot of detailed analysis and recoding, with almost
- -- certain performance penalties.
+ -- interrupts, though we could get away allowing Interrupt_Priority'last
+ -- where we are layered on an OS that does not allow us to mask interrupts.
+ -- Ideally, we would like to raise Program_Error back at the original point
+ -- of the RTS call, but this would require a lot of detailed analysis and
+ -- recoding, with almost certain performance penalties.
-- For POSIX systems, we considered just skipping setting priority ceiling
-- on RTS locks. This would mean there is no ceiling violation, but we
-- For now, we will just shut down the system if there is ceiling violation
+ procedure Set_Ceiling
+ (L : not null access Lock;
+ Prio : System.Any_Priority);
+ pragma Inline (Set_Ceiling);
+ -- Change the ceiling priority associated to the lock
+ --
+ -- The effect is undefined unless the calling task holds read or write
+ -- permission for the lock L, and L is the lock object most recently
+ -- locked by the calling task for which the calling task still holds
+ -- read or write permission. (That is, matching pairs of Lock and Unlock
+ -- operations on each lock object must be properly nested.)
+
procedure Yield (Do_Yield : Boolean := True);
pragma Inline (Yield);
-- Yield the processor. Add the calling task to the tail of the ready
-- Extensions --
----------------
- -- Whoever calls either of the Sleep routines is responsible
- -- for checking for pending aborts before the call.
- -- Pending priority changes are handled internally.
+ -- Whoever calls either of the Sleep routines is responsible for checking
+ -- for pending aborts before the call. Pending priority changes are handled
+ -- internally.
procedure Sleep
(Self_ID : ST.Task_Id;
Reason : System.Tasking.Task_States);
pragma Inline (Sleep);
- -- Wait until the current task, T, is signaled to wake up.
+ -- Wait until the current task, T, is signaled to wake up
--
-- precondition:
-- The calling task is holding its own ATCB lock
(Self_ID : ST.Task_Id;
Time : Duration;
Mode : ST.Delay_Modes);
- -- Implement the semantics of the delay statement. It is assumed that
- -- the caller is not abort-deferred and does not hold any locks.
+ -- Implement the semantics of the delay statement.
+ -- The caller should be abort-deferred and should not hold any locks.
procedure Wakeup
(T : ST.Task_Id;
-- setup/cleared upon entrance/exit of RTS while maintaining a single
-- thread of control in the RTS. Since we intend these routines to be used
-- for implementing the Single_Lock RTS, Lock_RTS should follow the first
- -- Defer_Abortion operation entering RTS. In the same fashion Unlock_RTS
- -- should preceed the last Undefer_Abortion exiting RTS.
+ -- Defer_Abort operation entering RTS. In the same fashion Unlock_RTS
+ -- should preceed the last Undefer_Abort exiting RTS.
--
-- These routines also replace the functions Lock/Unlock_All_Tasks_List
-- The call to Stack_Guard has no effect if guard pages are not used on
-- the target, or if guard pages are automatically provided by the system.
+ ------------------------
+ -- Suspension objects --
+ ------------------------
+
+ -- These subprograms provide the functionality required for synchronizing
+ -- on a suspension object. Tasks can suspend execution and relinquish the
+ -- processors until the condition is signaled.
+
+ function Current_State (S : Suspension_Object) return Boolean;
+ -- Return the state of the suspension object
+
+ procedure Set_False (S : in out Suspension_Object);
+ -- Set the state of the suspension object to False
+
+ procedure Set_True (S : in out Suspension_Object);
+ -- Set the state of the suspension object to True. If a task were
+ -- suspended on the protected object then this task is released (and
+ -- the state of the suspension object remains set to False).
+
+ procedure Suspend_Until_True (S : in out Suspension_Object);
+ -- If the state of the suspension object is True then the calling task
+ -- continues its execution, and the state is set to False. If the state
+ -- of the object is False then the task is suspended on the suspension
+ -- object until a Set_True operation is executed. Program_Error is raised
+ -- if another task is already waiting on that suspension object.
+
+ procedure Initialize (S : in out Suspension_Object);
+ -- Initialize the suspension object
+
+ procedure Finalize (S : in out Suspension_Object);
+ -- Finalize the suspension object
+
-----------------------------------------
-- Runtime System Debugging Interfaces --
-----------------------------------------
-- Such functionality is needed by gdb on some targets (e.g VxWorks)
-- Return True is the operation is successful
+ procedure Stop_All_Tasks;
+ -- Stop all tasks when the underlying thread library provides such
+ -- functionality. Such functionality is needed by gdb on some targets (e.g
+ -- VxWorks) This function can be run from an interrupt handler. Return True
+ -- is the operation is successful
+
+ function Continue_Task (T : ST.Task_Id) return Boolean;
+ -- Continue a specific task when the underlying thread library provides
+ -- such functionality. Such functionality is needed by gdb on some targets
+ -- (e.g VxWorks) Return True is the operation is successful
+
end System.Task_Primitives.Operations;