Interface implemented by all gate providers.
Gates are used serialize access to data structures that are used by more than one thread.
Gates are responsible for ensuring that only one out of multiple threads can access a data structure at a time. There are important scheduling latency and performance considerations that affect the "type" of gate used to protect each data structure. For example, the best way to protect a shared counter is to simply disable all interrupts before the update and restore the interrupt state after the update; disabling all interrupts prevents all thread switching, so the update is guaranteed to be "atomic". Although highly efficient, this method of creating atomic sections causes serious system latencies when the time required to update the data structure can't be bounded.
For example, a memory manager's list of free blocks can grow indefinitely long during periods of high fragmentation. Searching such a list with interrupts disabled would cause system latencies to also become unbounded. In this case, the best solution is to provide a gate that suspends the execution of threads that try to enter a gate that has already been entered; i.e., the gate "blocks" the thread until the thread already in the gate leaves. The time required to enter and leave the gate is greater than simply enabling and restoring interrupts, but since the time spent within the gate is relatively large, the overhead caused by entering and leaving gates will not become a significant percentage of overall system time. More importantly, threads that do not need to access the shared data structure are completely unaffected by threads that do access it.
#include <ti/syslink/utils/Trace.h>
Go to the source code of this file.
Data Structures | |
struct | IGateProvider_Object |
Defines | |
#define | IGateProvider_NULL (IGateProvider_Handle)0xFFFFFFFF |
#define | IGateProvider_Q_BLOCKING 1 |
#define | IGateProvider_Q_PREEMPTING 2 |
#define | IGateProvider_SuperObject |
#define | IGateProvider_ObjectInitializer(x, y) |
Typedefs | |
typedef IArg(* | IGateProvider_ENTER )(Void *) |
typedef Void(* | IGateProvider_LEAVE )(Void *, IArg) |
typedef struct IGateProvider_Object | IGateProvider_Object |
typedef struct IGateProvider_Object * | IGateProvider_Handle |
#define IGateProvider_NULL (IGateProvider_Handle)0xFFFFFFFF |
Invalid Igate
#define IGateProvider_Q_BLOCKING 1 |
======== IGateProvider_Q_BLOCKING ======== Blocking quality
Gates with this "quality" may cause the calling thread to block; i.e., suspend execution until another thread leaves the gate.
#define IGateProvider_Q_PREEMPTING 2 |
======== IGateProvider_Q_PREEMPTING ======== Preempting quality
Gates with this "quality" allow other threads to preempt the thread that has already entered the gate.
#define IGateProvider_SuperObject |
IGateProvider_ENTER enter; \ IGateProvider_LEAVE leave
======== IGateProvider_SuperObject ======== Object embedded in other Gate modules. (Inheritance)
#define IGateProvider_ObjectInitializer | ( | x, | |
y | |||
) |
((IGateProvider_Handle)(x))->enter = (IGateProvider_ENTER)y##_enter; \ ((IGateProvider_Handle)(x))->leave = (IGateProvider_LEAVE)y##_leave;
typedef IArg(* IGateProvider_ENTER)(Void *) |
Prototype of enter function
typedef Void(* IGateProvider_LEAVE)(Void *, IArg) |
Prototype of leave function
typedef struct IGateProvider_Object IGateProvider_Object |
Structure for generic gate instance
typedef struct IGateProvider_Object * IGateProvider_Handle |