SYS/BIOS  7.00
Data Structures | Typedefs | Functions
GateMutexPri.h File Reference

Detailed Description

Mutex Gate with priority inheritance.

GateMutexPri is a mutex gate (it can only be held by one thread at a time) which implements priority inheritance in order to prevent priority inversion. Priority inversion occurs when a high priority task has its priority effectively 'inverted' because it is waiting on a gate held by a low priority task.

When multiple tasks wait on this gate, they will receive the gate in order of priority (higher priority tasks will receive the gate first). This is because the queue of tasks waiting on a GateMutexPri is sorted by priority, not FIFO.

Problem: Priority Inversion

The following example demonstrates priority inversion. A system has three tasks, Low, Med, and High, each with the priority suggested by its name. Task Low runs first and acquires the gate. Task High is scheduled and preempts Low. Task High tries to acquire the gate, and waits on it. Next, task Med is scheduled and preempts task Low. Now task High must wait for both task Med and task Low to finish before it can continue. In this situation, task Low has in effect lowered task High's priority to that of Low.

Solution: Priority Inheritance

To guard against priority inversion, GateMutexPri implements priority inheritance: when task High tries to acquire a gate that is owned by task Low, task Low's priority will be temporarily raised to that of High, as long as High is waiting on the gate. Task High will "donate" its priority to task Low. When multiple tasks wait on the gate, the gate owner will receive the highest priority of any of the tasks waiting on the gate.

Caveats

Priority inheritance is not a complete guard against priority inversion. Tasks only donate priority on the call to gate, so if a task has its priority raised while waiting on a gate, that priority will not carry through to the gate owner. This can occur in situations involving multiple gates. A system has four tasks: VeryLow, Low, Med, and High, each with the priority suggested by its name. Task VeryLow runs first and acquires gate A. Task Low runs next and acquires gate B, then waits on gate A. Task High runs and waits on gate B. Task High has donated its priority to task Low, but Low is blocked on VeryLow, so priority inversion occurs despite the use of the gate. The solution to this problem is to design around it. If gate A may be needed by a high-priority, time-critical task, then it should be a design rule that no task holds this gate for a long time, or blocks while holding this gate.

Miscellaneous

Calls to enter() may block, so this gate can only be used in the task context. GateMutexPri is non-deterministic on calls to gate because it keeps the queue of waiting tasks sorted by priority.

Calling Context

Function Hwi Swi Task Main Startup
@link GateMutexPri_Params_init @endlink Y Y Y Y Y
@link GateMutexPri_query @endlink Y Y Y Y Y
@link GateMutexPri_construct @endlink Y Y Y Y N
@link GateMutexPri_create @endlink N* N* Y Y N
@link GateMutexPri_delete @endlink N* N* Y Y N
@link GateMutexPri_destruct @endlink Y Y Y Y N
@link GateMutexPri_enter @endlink N N Y Y** N
@link GateMutexPri_leave @endlink N N Y Y** N
Definitions:
  • Hwi: API is callable from a Hwi thread.
  • Swi: API is callable from a Swi thread.
  • Task: API is callable from a Task thread.
  • Main: API is callable during any of these phases:
    • In your module startup after this module is started (e.g. GateMutexPri_Module_startupDone() returns true).
    • During xdc.runtime.Startup.lastFxns.
    • During main().
    • During BIOS.startupFxns.
  • Startup: API is callable during any of these phases:
    • During xdc.runtime.Startup.firstFxns.
    • In your module startup before this module is started (e.g. GateMutexPri_Module_startupDone() returns false).
  • *: Assuming blocking Heap is used for creation.
  • **: Must be used in enter/leave pairs.

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/runtime/Error.h>
Include dependency graph for GateMutexPri.h:

Go to the source code of this file.

Data Structures

struct  GateMutexPri_Params
 
struct  GateMutexPri_Struct
 

Typedefs

typedef struct GateMutexPri_Params GateMutexPri_Params
 
typedef struct GateMutexPri_Struct GateMutexPri_Struct
 
typedef struct GateMutexPri_Struct GateMutexPri_Object
 
typedef GateMutexPri_ObjectGateMutexPri_Handle
 

Functions

bool GateMutexPri_canBePreempted (void)
 query Gate 'preempt' characteristics More...
 
bool GateMutexPri_canBlock (void)
 query Gate 'blocking' characteristics More...
 
GateMutexPri_Handle GateMutexPri_create (const GateMutexPri_Params *prms, Error_Block *eb)
 Create a GateMutexPri gate. More...
 
GateMutexPri_Handle GateMutexPri_construct (GateMutexPri_Struct *obj, const GateMutexPri_Params *prms)
 Construct a GateMutexPri gate. More...
 
void GateMutexPri_delete (GateMutexPri_Handle *gate)
 Delete a GateMutexPri gate. More...
 
void GateMutexPri_destruct (GateMutexPri_Struct *obj)
 Destruct a GateMutexPri gate. More...
 
void GateMutexPri_Params_init (GateMutexPri_Params *prms)
 Initialize the GateMutexPri_Params structure with default values. More...
 
intptr_t GateMutexPri_enter (GateMutexPri_Handle gate)
 enter the GateMutexPri gate More...
 
void GateMutexPri_leave (GateMutexPri_Handle gate, intptr_t key)
 leave the GateMutexPri gate More...
 
GateMutexPri_Handle GateMutexPri_Object_first (void)
 return handle of the first GateMutexPri on GateMutexPri list More...
 
GateMutexPri_Handle GateMutexPri_Object_next (GateMutexPri_Handle gate)
 return handle of the next GateMutexPri on GateMutexPri list More...
 

Typedef Documentation

§ GateMutexPri_Params

§ GateMutexPri_Struct

§ GateMutexPri_Object

§ GateMutexPri_Handle

Function Documentation

§ GateMutexPri_canBePreempted()

bool GateMutexPri_canBePreempted ( void  )

query Gate 'preempt' characteristics

GateMutexPri can be preempted. This API always returns true.

Return values
true

§ GateMutexPri_canBlock()

bool GateMutexPri_canBlock ( void  )

query Gate 'blocking' characteristics

GateMutexPri enter can block if another task owns the gate. This API always returns true.

Return values
true

§ GateMutexPri_create()

GateMutexPri_Handle GateMutexPri_create ( const GateMutexPri_Params prms,
Error_Block eb 
)

Create a GateMutexPri gate.

Parameters
prmsoptional parameters
eberror block
Return values
GateMutexPrihandle (NULL on failure)

§ GateMutexPri_construct()

GateMutexPri_Handle GateMutexPri_construct ( GateMutexPri_Struct obj,
const GateMutexPri_Params prms 
)

Construct a GateMutexPri gate.

GateMutexPri_construct is equivalent to GateMutexPri_create except that the GateMutexPri_Struct is pre-allocated.

Parameters
objpointer to a GateMutexPri object
prmsoptional parameters
Return values
GateMutexPrihandle (NULL on failure)

§ GateMutexPri_delete()

void GateMutexPri_delete ( GateMutexPri_Handle gate)

Delete a GateMutexPri gate.

Note that GateMutexPri_delete takes a pointer to a GateMutexPri_Handle which enables GateMutexPri_delete to set the GateMutexPri handle to NULL.

Parameters
gatepointer to a GateMutexPri handle

§ GateMutexPri_destruct()

void GateMutexPri_destruct ( GateMutexPri_Struct obj)

Destruct a GateMutexPri gate.

Parameters
objpointer to a GateMutexPri objects

§ GateMutexPri_Params_init()

void GateMutexPri_Params_init ( GateMutexPri_Params prms)

Initialize the GateMutexPri_Params structure with default values.

GateMutexPri_Params_init initializes the GateMutexPri_Params structure with default values. GateMutexPri_Params_init should always be called before setting individual parameter fields. This allows new fields to be added in the future with compatible defaults – existing source code does not need to change when new fields are added.

Parameters
prmspointer to uninitialized params structure

§ GateMutexPri_enter()

intptr_t GateMutexPri_enter ( GateMutexPri_Handle  gate)

enter the GateMutexPri gate

GateMutexPri_enter enters the GateMutexPri gate and returns a key for use by GateMutexPri_enter. GateMutexPri_enter calls can be nested and the key is used to unlock the gate on the final call to GateMutexPri_leave.

Parameters
gateGateMutexPri handle
Return values
opaquekey to be passed to GateMutexPri_leave()

§ GateMutexPri_leave()

void GateMutexPri_leave ( GateMutexPri_Handle  gate,
intptr_t  key 
)

leave the GateMutexPri gate

GateMutexPri_leave exits the GateMutexPri gate if key matches the outermost call to GateMutexPri_enter. If GateMutexPri_enter calls are nested, the key will keep the nested calls from leaving the gate.

Parameters
gateGateMutexPri handle
keyopaque key to unlock the gate

§ GateMutexPri_Object_first()

GateMutexPri_Handle GateMutexPri_Object_first ( void  )

return handle of the first GateMutexPri on GateMutexPri list

Return the handle of the first GateMutexPri on the create/construct list. NULL if no GateMutexPris have been created or constructed.

Return values
GateMutexPrihandle

§ GateMutexPri_Object_next()

GateMutexPri_Handle GateMutexPri_Object_next ( GateMutexPri_Handle  gate)

return handle of the next GateMutexPri on GateMutexPri list

Return the handle of the next GateMutexPri on the create/construct list. NULL if no more GateMutexPris are on the list.

Parameters
gateGateMutexPri handle
Return values
GateMutexPrihandle
© Copyright 1995-2022, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale