![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Mutexes and Condition Variables (Package V_Mutexes) This section contains an overview describing this package. This overview section is followed by a detailed description of each subprogram in this package.
The following topics are covered in this section:
Package OverviewDescription
Package V_Mutexes provides mutexes and condition variables. It is layered directly on top of the V_I_Mutex package, which provides abort-safe mutexes and condition variables.
There are two varieties of mutexes: normal and recursive.
Normal mutexes can be used in conjunction with condition variables and provide the functionality described in Posix 1003.4a.
Recursive mutexes cannot be used in conjunction with condition variables; this is enforced by the typing system. Recursive mutexes are layered on top of normal mutexes, and support recursive locking by a given task. That is, when a task succeeds in locking a given mutex, it can recursively lock the mutex without blocking. Subsequent unlocks do not release the lock until the recursion depth has reached 0. Recursive mutexes detect and raise exceptions for invalid unlock and delete operations.
Mutexes (both normal and recursive) can be created with specific attributes. If the underlying kernel does not support the attribute, an exception is raised during creation.
Condition variables can also be created with specific queuing behavior. If the underlying kernel does not support the specified behavior, an exception is raised during creation.
Mutexes and condition variables can be shared between programs by using the bind and resolve name services.
Mutex operations are provided to create, delete, bind, resolve, lock, and unlock mutexes.
Priority-ceiling-specific mutex operations are provided to set and return the priority ceiling of a mutex.
Condition variable operations are provided to create, delete, bind, resolve, signal, broadcast, and wait.
Package Procedures and Functions
Table 12 lists the procedures and functions in package V_Mutexes with a brief description of each subprogram.
Types
Table 13 lists the types used in package V_Mutexes
Constants
Table 14 lists the types used in package V_Mutexes
Mutex Exceptions
Table 15 lists the mutex exceptions used in package V_Mutexes
Condition Variable Exceptions
Table 16 lists the condition variable exceptions used in package V_Mutexes
Package Specification
with System; use System; with ADA_Krn_Defs; with V_I_CIFO; with V_InterruptS; package V_Mutexes is
pragma SUPPRESS( ALL_Checks );
type mutex_id is private;
type r_mutex_id is private;
type cond_id is private;
type cond_result is ( OBTAINED, TIMED_OUT );
Wait_Forever : constant duration := -1.0; DO_NOT_Wait : constant duration := 0.0;
NO_Memory_FOR_MUTEX : exception;
MUTEX_ATTR_NOT_SUPPORTED : exception;
MUTEX_LOCKED : exception;
Bind_Mutex_NOT_SUPPORTED : exception;
Bind_Mutex_BAD_ARGUMENT : exception;
NO_Memory_FOR_MUTEX_NAME : exception;
MUTEX_NAME_ALREADY_BOUND : exception;
Resolve_Mutex_NOT_SUPPORTED : exception;
Resolve_Mutex_BAD_ARGUMENT : exception;
Resolve_Mutex_TIMED_OUT : exception;
Resolve_Mutex_FAILED : exception;
NOT_A_MUTEX_NAME : exception;
UNEXPECTED_V_MUTEX_ERROR : exception;
NO_Memory_FOR_COND : exception;
COND_QUEUING_NOT_SUPPORTED : exception;
COND_TIMED_OUT : exception;
Bind_Cond_NOT_SUPPORTED : exception;
Bind_Cond_BAD_ARGUMENT : exception;
NO_Memory_FOR_COND_NAME : exception;
COND_NAME_ALREADY_BOUND : exception;
Resolve_Cond_NOT_SUPPORTED : exception;
Resolve_Cond_BAD_ARGUMENT : exception;
Resolve_Cond_TIMED_OUT : exception;
Resolve_Cond_FAILED : exception;
NOT_A_COND_NAME : exception;
UNEXPECTED_V_COND_ERROR : exception;
procedure Create_Mutex (mutex : out mutex_id; attr : in ADA_Krn_Defs.a_mutex_attr_t := ADA_Krn_Defs.DEFAULT_MUTEX_ATTR);
procedure Create_Mutex (mutex : out r_mutex_id; attr : in ADA_Krn_Defs.a_mutex_attr_t := ADA_Krn_Defs.DEFAULT_MUTEX_ATTR);
function Create_Mutex (attr : in ADA_Krn_Defs.a_mutex_attr_t := ADA_Krn_Defs.DEFAULT_MUTEX_ATTR) return mutex_id;
function Create_Mutex (attr : in ADA_Krn_Defs.a_mutex_attr_t := ADA_Krn_Defs.DEFAULT_MUTEX_ATTR) return r_mutex_id;
procedure Delete_Mutex (mutex : in out mutex_id); procedure Delete_Mutex (mutex : in out r_mutex_id);
procedure Bind_Mutex (name : in string; mutex : in mutex_id); procedure Bind_Mutex (name : in string; mutex : in r_mutex_id);
procedure Resolve_Mutex (name : in string; mutex : out mutex_id; wait_time : in duration := Wait_Forever);
procedure Resolve_Mutex (name : in string; mutex : out r_mutex_id; wait_time : in duration := Wait_Forever); function Resolve_Mutex (name : in string; wait_time: in duration := Wait_Forever) return mutex_id; function Resolve_Mutex (name : in string; wait_time: in duration := Wait_Forever) return r_mutex_id;
procedure Lock_Mutex (mutex : in mutex_id); procedure Lock_Mutex (mutex : in r_mutex_id); pragma Inline_Only(Lock_Mutex);
function Trylock_Mutex (mutex : in mutex_id) return boolean; function Trylock_Mutex (mutex : in r_mutex_id) return boolean; pragma Inline_Only(Trylock_Mutex);
procedure Unlock_Mutex (mutex : in mutex_id); procedure Unlock_Mutex (mutex : in r_mutex_id); pragma Inline_Only(Unlock_Mutex);
procedure Set_PRIORITY_CEILING (mutex : in mutex_id; ceil_pri : in priority); procedure Set_PRIORITY_CEILING (mutex : in r_mutex_id; ceil_pri : in priority);
function Get_PRIORITY_CEILING (mutex : in mutex_id) return integer; function Get_PRIORITY_CEILING (mutex : in r_mutex_id) return integer;
procedure Create_Cond (cond : out cond_id; queuing : in V_I_CIFO.queuing_t := V_I_CIFO.ARBITRARY_QUEUING; abort_callout_proc : in address := NO_ADDR; abort_arg : in address := NO_ADDR);
function Create_Cond (queuing : in V_I_CIFO.queuing_t := V_I_CIFO.ARBITRARY_QUEUING; abort_callout_proc : in address := NO_ADDR; abort_arg : in address := NO_ADDR) return cond_id;
procedure Delete_Cond (cond : in out cond_id);
procedure Bind_Cond (name : in string; cond : in cond_id);
procedure Resolve_Cond (name : in string; cond : out cond_id; wait_time : in duration := Wait_Forever); function Resolve_Cond (name : in string; wait_time : in duration := Wait_Forever) return cond_id;
procedure Signal_Cond (cond : in cond_id); pragma Inline_Only(Signal_Cond);
procedure Signal_Unlock_Cond (cond : in cond_id; mutex : in mutex_id); pragma Inline_Only(Signal_Unlock_Cond);
procedure Broadcast_Cond (cond : in cond_id); pragma Inline_Only(Broadcast_Cond);
procedure Wait_Cond (cond : in cond_id; mutex : in mutex_id); pragma Inline_Only(Wait_Cond);
procedure Timed_Wait_Cond (cond : in cond_id; mutex : in mutex_id; sec : in duration); function Timed_Wait_Cond (cond : in cond_id; mutex : in mutex_id; sec : in duration) return cond_result;
private
type mutex_rec; type mutex_id is access mutex_rec;
type r_mutex_rec; type r_mutex_id is access r_mutex_rec;
type cond_rec; type cond_id is access cond_rec;
end V_Mutexes;
Procedures and Functions in Package V_Mutexesprocedure Bind_Cond
Syntax
procedure Bind_Cond (name : in string; cond : in cond_id);Arguments
- name
Condition variable name. The name can be any sequence of characters. An exact match is done for all name searches. (My_Cond is different from my_cond.)
- cond
Description
Bind_Cond binds a name to a previously created condition variable.
Exceptions
- No_Memory_For_Cond_Name
Raised if an attempt is made to bind a name to a condition variable and there is insufficient memory.
- Bind_Cond_Not_Supported
Raised if name services are not supported by the underlying RTS.
- Bind_Cond_Bad_Argument
Raised if Bind_Cond is called with a null name.
- Cond_Name_Already_Bound
Raised if an attempt is made to bind a name to a condition variable and the name has already been bound to another object or procedure.
Warning: For native, names are only known within a single program. Name binding and resolution services are more applicable to the cross-target environment.
procedure Bind_Mutex
Syntax
procedure Bind_Mutex (name : in string; mutex : in mutex_id); procedure Bind_Mutex (name : in string; mutex : in r_mutex_id);Arguments
- name
Mutex name. The name can be any sequence of characters. An exact match is done for all name searches. (MY_MUTEX is different from my_mutex.)
- mutex
Description
Bind_Mutex binds a name to a previously created mutex.
Exceptions
- No_Memory_For_Mutex_Name
Raised if an attempt is made to bind a name to a mutex and there is insufficient memory.
- Bind_Mutex_Not_Supported
Raised if name services are not supported by the underlying RTS.
- Bind_Mutex_Bad_Argument
Raised if Bind_Mutex is called with a null name.
- Mutex_Name_Already_Bound
Raised if an attempt is made to bind a name to a mutex and the name has already been bound to another object or procedure.
Warning: For native, names are only known within a single program. Name binding and resolution services are more applicable to the cross-target environment.
procedure Broadcast_Cond
Syntax
procedure Broadcast_Cond (cond : in cond_id); pragma Inline_Only(Broadcast_Cond);Arguments
Description
procedure Broadcast_Cond broadcasts a condition variable, "waking up" all tasks that are waiting on the condition variable. However, no awakened task resumes execution until the associated mutex is unlocked.
procedure/function Create_Cond
Syntax
procedure Create_Cond (cond : out cond_id; queuing : in V_I_CIFO.queuing_t := V_I_CIFO.ARBITRARY_QUEUING; abort_callout_proc : in address := NO_ADDR; abort_arg : in address := NO_ADDR); function Create_Cond (queuing : in V_I_CIFO.queuing_t := V_I_CIFO.ARBITRARY_QUEUING; abort_callout_proc : in address := NO_ADDR; abort_arg : in address := NO_ADDR) return cond_id;Arguments
- abort_callout_proc
procedure to call before completing the task abort sequence. Default is No_Addr, which implies that no call is done. The procedure has the following specification:
procedure abort_callout_proc( abort_arg : in address
If not No_Addr, the procedure is called with the abort_arg argument
- abort_arg
Argument (of arbitrary type) to the Abort_Callout_Proc. [Default: No_Addr]
- cond
- queuing
Description
Subprogram Create_Cond creates and initializes a condition variable. Two versions are supplied: a procedure that returns Cond_Id as an out parameter, and a function that returns Cond_Id as the result.
The created condition variable can be shared with other programs by using the Bind_Cond/Resolve_Cond services.
For a description of condition variable queuing behaviors, see v_i_cifo.a.
Here are some examples of usage:
cond : cond_id; queueing : V_I_CIFO.queuing_t := ... procedure abort_proc( arg : in address ); i : integer;
- Creates a condition variable with default queuing behavior:
cond := Create_Cond;
- Creates a condition variable with priority queuing behavior. Note that the exception Cond_Queuing_Not_Supported is raised if the underlying kernel does not support priority queuing on condition variables:
Create_Cond( cond, V_I_CIFO.PRIORITY_QUEUING );
- Creates a condition variable (with default queuing behavior) for which the specified abort procedure is called with the specified argument, if the task is aborted:
Create_Cond(abort_callout_proc :=abort_proc'address, abort_arg := i'address );
Exceptions
- No_Memory_For_Cond
Raised by Create_Cond if an attempt is made to create a condition variable and there is insufficient memory for the condition variable object in the system pool.
- Cond_Queuing_Not_Supported
Raised by Create_Cond if the underlying kernel does not support the specified queuing behavior.
procedure/function Create_Mutex
Syntax
procedure Create_Mutex (mutex : out mutex_id; attr : in ADA_Krn_Defs.a_mutex_attr_t := ADA_Krn_Defs.DEFAULT_MUTEX_ATTR);
procedure Create_Mutex (mutex : out r_mutex_id; attr : in ADA_Krn_Defs.a_mutex_attr_t := ADA_Krn_Defs.DEFAULT_MUTEX_ATTR); function Create_Mutex (attr : in ADA_Krn_Defs.a_mutex_attr_t := ADA_Krn_Defs.DEFAULT_MUTEX_ATTR) return mutex_id; function Create_Mutex (attr : in ADA_Krn_Defs.a_mutex_attr_t := ADA_Krn_Defs.DEFAULT_MUTEX_ATTR) return r_mutex_id;Arguments
Description
Create_Mutex creates and initializes a mutex. Two versions are supplied: a procedure that returns Mutex_Id as an out parameter, and a function returning Mutex_Id as the result.
The created mutex can be shared with other programs by using the Bind_Mutex/Resolve_Mutex services.
For a description of mutex attributes, see ada_krn_defs.a in the standard directory.
Here are some examples of usage:
mutex : mutex_id; r_mutex : r_mutex_id; intr_mask : ADA_Krn_Defs.intr_status_t := ...
- Creates a (recursive) mutex with default attributes:
r_mutex := Create_Mutex;
- Creates a mutex with priority queue waiting:
Create_Mutex(mutex,ADA_Krn_Defs.prio_mutex_attr_init);
- Creates a mutex suitable for using in an interrupt service routine, which uses the mask specified by the caller:
mutex := Create_Mutex(ADA_Krn_Defs.intr_attr_init(intr_mask));
- Creates a (recursive) mutex that uses the priority ceiling emulation algorithm described in Posix 1003.4a. Note that this results in the exception Mutex_Attr_Not_Supported being raised if the underlying kernel does not support the priority ceiling algorithm:
Create_Mutex( r_mutex,prio_inherit_mutex_attr_init );
Exceptions
- No_Memory_For_Mutex
Raised by Create_Mutex if an attempt is made to create a mutex and there is insufficient memory for the mutex. object in the system pool
- Mutex_Attr_Not_Supported
Raised by Create_Mutex if the underlying kernel does not support the specified attribute.
procedure Delete_Cond
Syntax
procedure Delete_Cond (cond : in out cond_id);Arguments
Description
procedure Delete_Cond deletes a previously created condition variable.
If a condition variable is shared between programs by using the Bind_Cond/Resolve_Cond services, it must be deleted only in the program where it was created.
procedure Delete_Mutex
Syntax
procedure Delete_Mutex (mutex : in out mutex_id); procedure Delete_Mutex (mutex : in out r_mutex_id);Arguments
Description
procedure Delete_Mutex deletes a previously created mutex.
If a mutex is shared between programs by using the Bind_Mutex/Resolve_Mutex services, it must be deleted only in the program where it was created.
Exceptions
function Get_Priority_Ceiling_Mutex
Syntax
function Get_Priority_Ceiling_Mutex (mutex : in mutex_id) return integer; function Get_Priority_Ceiling_Mutex (mutex : in r_mutex_id) return integer;Arguments
Description
function Get_Priority_Ceiling_Mutex returns the ceiling priority of the given mutex.
Exceptions
- Mutex_Attr_Not_Supported
Raised if either the priority ceiling protocol is not supported, or the mutex is not a priority ceiling mutex.
procedure Lock_Mutex
Syntax
procedure Lock_Mutex (mutex : in mutex_id); procedure Lock_Mutex (mutex : in r_mutex_id); pragma Inline_Only(Lock_Mutex);Arguments
Description
procedure Lock_Mutex attempts to lock the mutex.
For non-recursive mutexes, if the mutex is currently locked, the task is blocked until the mutex is no longer locked and there are no other tasks waiting "ahead" associated with the mutex. Attempting to lock a mutex that is already locked by the calling task results in an infinite wait for the calling task.
For recursive mutexes, if the mutex is currently locked by the calling task, the depth is incremented and no blocking occurs. If the mutex is locked by another task, the task is blocked until the mutex is no longer locked and there are no other tasks waiting ahead of it.
procedure/function Resolve_Cond
Syntax
procedure Resolve_Cond (name : in string; cond : out cond_id; wait_time : in duration := Wait_Forever); function Resolve_Cond (name : in string; wait_time : in duration := Wait_Forever) return cond_id;Arguments
- name
- cond
- wait_time
Amount of time the user is willing to wait for the name to be bound. Two allowable predefined values are:
Description
Subprogram Resolve_Cond resolves a name into a condition variable that is created and bound in another program. Two versions are supplied: a procedure that returns Cond_Id as an out parameter, and a function that returns Cond_Id as the result.
subprogram Resolve_Cond first attempts to find an already bound name that exactly matches the name parameter. For a match, it returns immediately. Otherwise, it returns according to the wait_time parameter.
Exceptions
- Resolve_Cond_Not_Supported
Raised if name services are not supported by the underlying RTS.
- Resolve_Cond_Bad_Argument
Raised if Resolve_Cond is called with a null name.
- Resolve_Cond_Timed_Out
Raised by Resolve_Cond if a timed wait is attempted and the name is not bound to a condition variable in the given time interval.
- Resolve_Cond_Failed
Raised by Resolve_Cond if a non-waited attempt is made to resolve a name to a condition variable, and the name is not already bound.
- Not_A_Cond_Name
Raised by Resolve_Cond if the name is bound, but not to a condition variable object.
Warning: For native, names are only known within a single program. Name binding and resolution services are more applicable to the cross-target environment.
procedure/function Resolve_Mutex
Syntax
procedure Resolve_Mutex (name : in string; mutex : out mutex_id; wait_time : in duration := Wait_Forever); procedure Resolve_Mutex (name : in string; mutex : out r_mutex_id; wait_time : in duration := Wait_Forever); function Resolve_Mutex (name : in string; wait_time : in duration := Wait_Forever) return mutex_id; function Resolve_Mutex (name : in string; wait_time : in duration := Wait_Forever) return r_mutex_id;Arguments
- mutex
- name
- wait_time
Amount of time the user is willing to wait for the name to be bound. Two allowable predefined values are:
Description
Subprogram Resolve_Mutex resolves a name into a mutex that is created and bound in another program. Two versions are supplied: a procedure that returns Mutex_Id as an out parameter, and a function that returns Mutex_Id as the result.
Subprogram Resolve_Mutex first attempts to find an already bound name that exactly matches the name parameter. For a match, it returns immediately. Otherwise, it returns according to the wait_time parameter.
Exceptions
- Resolve_Mutex_Not_Supported
Raised if name services are not supported by the underlying RTS.
- Resolve_Mutex_Bad_Argument
Raised if Resolve_Mutex is called with a null name.
- Resolve_Mutex_Timed_Out
Raised by Resolve_Mutex if a timed wait is attempted and the name is not bound to a mutex in the given time interval.
- Resolve_Mutex_Failed
Raised by Resolve_Mutex if a non-waited attempt is made to resolve a name to a mutex, and the name is not already bound.
- Not_A_Mutex_Name
Raised by Resolve_Mutex if the name is bound, but not to a mutex object.
Warning: For native, names are only known within a single program. Name binding and resolution services are more applicable to the cross-target environment.
procedure Set_Priority_Ceiling_Mutex
Syntax
procedure Set_Priority_Ceiling_Mutex (mutex : in mutex_id; ceil_prio : in priority); procedure Set_Priority_Ceiling_Mutex (mutex : in r_mutex_id; ceil_prio : in priority);Arguments
Description
procedure Set_Priority_Ceiling sets the given mutex priority ceiling.
Exceptions
- Mutex_Attr_Not_Supported
Raised if the priority ceiling protocol is not supported, or the given mutex is not a priority ceiling mutex.
procedure Signal_Cond
Syntax
procedure Signal_Cond (cond : in cond_id); pragma Inline_Only(Signal_Cond);Arguments
Description
procedure Signal_Cond signals a condition variable, "waking up" the next (as defined by the queuing behavior) task that is waiting on the condition variable. However, the awakened task does not resume execution until the associated mutex is unlocked.
procedure Signal_Unlock_Cond
Syntax
procedure Signal_Unlock_Cond (cond : in cond_id; mutex : in mutex_id); pragma Inline_Only(SIgnal_Unlock_Cond);Arguments
Description
procedure SIgnal_Unlock_Cond signals a condition variable and unlocks the specified mutex. This is more efficient than separate calls to Signal_Cond and Unlock_Mutex.
procedure/function Timed_Wait_Cond
Syntax
procedure Timed_Wait_Cond (cond : in cond_id; mutex : in mutex_id; sec : in duration); function Timed_Wait_Cond (cond : in cond_id; mutex : in mutex_id; sec : in duration) return cond_result;Arguments
Description
Subprogram Timed_Wait_Cond blocks the calling task on the condition variable until either a corresponding signal/broadcast is performed on the condition variable, or the time duration has expired (assuming the duration is positive). If the duration is zero, it returns immediately, without blocking. If the duration is negative, it does not time out; that is, it waits indefinitely. There are two versions: the procedure raises an exception on timeout (otherwise, it returns normally), and the function returns the result of the wait. If successful, the calling task holds the lock on the mutex upon return.
Exceptions
function Trylock_Mutex
Syntax
function Trylock_Mutex (mutex : in mutex_id) return boolean; function Trylock_Mutex (mutex : in r_mutex_id) return boolean; pragma Inline_Only(Trylock_Mutex);Arguments
Description
Function Trylock_Mutex attempts to lock the mutex. If the mutex is already locked, it returns False. Otherwise, it locks the mutex (as specified by the Lock_Mutex routine) and returns True. No blocking ever occurs as a result of this call.
procedure Unlock_Mutex
Syntax
procedure Unlock_Mutex (mutex : in mutex_id); procedure Unlock_Mutex (mutex : in r_mutex_id); pragma Inline_Only(Unlock_Mutex);Arguments
Description
Procedure Unlock_Mutex unlocks the mutex, enabling the next task waiting to lock the mutex to proceed. If the mutex is a recursive mutex, however, the depth is first decremented. If the subsequent depth is greater than zero, the calling task retains the lock. If the depth is zero, then the lock is given up.
Exceptions
- Unexpected_V_Mutex_Error
Raised if a recursive mutex is unlocked by some task other than the owner or when the depth is 0.
procedure Wait_Cond
Syntax
procedure Wait_Cond (cond : in cond_id; mutex : in mutex_id); pragma Inline_Only(Wait_Cond);Arguments
Description
Procedure Wait_Cond blocks the calling task until a corresponding signal/broadcast is performed on the condition variable, and the mutex is unlocked. It is possible, however, that a task may return from Wait_Cond "early", because of an abort and/or other operating-system events (see V_I_Mutex). It is therefore essential that calls to Wait_Cond be wrapped inside a loop that tests for the associated predicate before proceeding. Upon return from Wait_Cond, the mutex is locked by the calling task.
Rational Software Corporation http://www.rational.com support@rational.com techpubs@rational.com Copyright © 1993-2003, Rational Software Corporation. All rights reserved. |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |