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 execution 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 used by code that is called
by ISRs and gates that are not "preemptible" should only be used 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 the
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 Wed, 28 Aug 2019 17:00:48 GMT