Critical section support
Gates are used by clients to protect concurrent access to critical
data structures. Critical data structures are those that must be
updated by at most one thread at a time. All code that needs access
to a critical data structure "enters" a gate (that's associated with the
data structure) prior to accessing the data, modifies the data structure,
then "leaves" the gate.
[
more ... ]
#include <xdc/runtime/Gate.h>
Functions |
| |
macro Bool | |
macro Bool | |
macro IArg | |
macro IArg | |
IArg | |
macro Void | |
macro Void | |
macro Void | |
Void | |
Functions common to all target modules |
|
|
Typedefs |
typedef opaque | |
DETAILS
Gates are used by clients to protect concurrent access to critical
data structures. Critical data structures are those that must be
updated by at most one thread at a time. All code that needs access
to a critical data structure "enters" a gate (that's associated with the
data structure) prior to accessing the data, modifies the data structure,
then "leaves" the gate.
A gate is responsible for ensuring that at most one thread at a time
can enter and execute "inside" the gate. There are several
implementations of gates, with different system executation times and
latency tradoffs. In addition, some gates must not be entered by certain
thread types; e.g., a gate that is implemented via a "blocking" semaphore
must not be called by an interrupt service routine (ISR).
A module can be declared "gated" by adding the
@Gated attribute to the
module's XDC spec file. A "gated" module is assigned a module-level gate
at the configuration time, and that gate is then used to protect critical
sections in the module's target code. A module-level gate is an instance of
a module implementing
IGateProvider interface. However, gated
modules do not access their module-level gates directly. They use this
module to access transparently their module-level gate.
Application code that is not a part of any module also has a
module-level gate, configured through the module
Main.
Each gated module can optionally create gates on an adhoc basis at
runtime using the same gate module that was used to create the module
level gate.
Gates that work by disabling all preemption while inside a gate can be
used to protect data structures accessed by ISRs and other
threads. But, if the time required to update the data structure is not
a small constant, this type of gate may violate a system's real-time
requirements.
Gates have two orthogonal attributes: "blocking" and "preemptible".
In general, gates that are "blocking" can not be use by code that is
called by ISRs and gates that are not "preemptible" should only be used to
to protect data manipulated by code that has small constant execution
time.
typedef Gate_Ref |
|
Opaque reference to an allocated gate instance
Gate_allocInstance() // module-wide |
|
Allocate a gate instance from the current module's gate
ARGUMENTS
eb
Error block pointer
If NULL, any error in creating the instance will terminate
the application.
DETAILS
This method is used by modules to create gates at runtime using
the same
IGateProvider that was used to create the module
level gate. The parameters passed to the
IGateProvider are
specified at configuration time via the
Types.Common$.gateParams
configuration parameter.
RETURNS
Non-NULL instance handle is returned if no error occurs; otherwise
an error is raised in eb and NULL is returned.
SEE
Gate_canBePreempted() // module-wide |
|
Check if the module level gate allows thread preemption
macro Bool Gate_canBePreempted();
DETAILS
This type of gate should always be used by clients that protect
a data structure whose updates require more than a small
constant amount of time; e.g., update of a memory allocator's free
list.
RETURNS
Returns TRUE if the underlying gate does not disable
thread preemption.
Gate_canBlock() // module-wide |
|
Check if the module level gate can block threads
macro Bool Gate_canBlock();
DETAILS
This type of gate should never be called by clients that must never
call a "blocking" RTOS operation; e.g., interrupt service
routines
RETURNS
Returns TRUE if the underlying gatekeeper's gate can
block
Gate_enterInstance() // module-wide |
|
Enter a critical section protected by this gate instance
macro IArg Gate_enterInstance(
Gate_Ref gate);
ARGUMENTS
RETURNS
Returns a "key" value that must be used to leave
gate
via
leaveInstance().
Gate_enterModule() // module-wide |
|
Enter a critical section protected by the current module's gate
macro IArg Gate_enterModule();
RETURNS
Returns a "key" value that must be used to leave the current module
gate via
leaveModule().
SEE
Gate_enterSystem() // module-wide |
|
Enter a critical section protected by the global System gate
RETURNS
Returns a "key" value that must be used to leave the
System
gate via
leaveSystem().
SEE
Gate_freeInstance() // module-wide |
|
Free a gate instance to the current module's gatekeeper
macro Void Gate_freeInstance(
Gate_Ref gate);
ARGUMENTS
SEE
Gate_leaveInstance() // module-wide |
|
Leave a critical section protected by a gate
macro Void Gate_leaveInstance(
Gate_Ref gate,
IArg key);
ARGUMENTS
SEE
Gate_leaveModule() // module-wide |
|
Leave a critical section protected by the current module's gate
macro Void Gate_leaveModule(IArg key);
ARGUMENTS
SEE
Gate_leaveSystem() // module-wide |
|
Leave a critical section protected by the global System gate
Void Gate_leaveSystem(IArg key);
ARGUMENTS
SEE
Module-Wide Built-Ins |
|
// Get this module's unique id
Bool Gate_Module_startupDone();
// Test if this module has completed startup
// The heap from which this module allocates memory
Bool Gate_Module_hasMask();
// Test whether this module has a diagnostics mask
Bits16 Gate_Module_getMask();
// Returns the diagnostics mask for this module
Void Gate_Module_setMask(Bits16 mask);
// Set the diagnostics mask for this module
var Gate = xdc.useModule('xdc.runtime.Gate');
module-wide config parameters
module-wide functions
generated on Thu, 03 Feb 2011 19:01:53 GMT