Mutexes are used to synchronize access by cooperating tasks to shared resources. For every shared resource, create an associated shared mutex. Mutexes should be locked by a task before beginning usage of the shared resource and then unlocked after the usage is over. A task cannot lock a mutex that is already locked by another mutex. It will either block for the mutex to unlock or will return an error code (depending on the options used). Mutexes must always be used in a lock/unlock sequence.
mutex_t resource_mutex; // Previously initialized (possibly in main) void task1(void *dummy) { while(1) { mutex_lock(&resource_mutex, 0, 0); do_stuff(); mutex_unlock(&resource_mutex); do_other_stuff(); } }
A detailed description of the design and implementation of mutexes within TiROS are provided in the Mutual Exclusion (Mutex) section.
NOTE: Always initialize before use.
Functions | |
void | mutex_init (mutex_t *m, tid_t prio_ceiling) |
tid_t | mutex_owner (mutex_t *m) |
int8_t | mutex_lock (mutex_t *m, const trtime_t *timeout, uint8_t options) |
int8_t | mutex_unlock (mutex_t *m) |
Initialize mutex.
Calling Context:
m | Pointer to mutex structure | |
prio_ceiling | The priority ceiling, if the priority celing protocol is used. If priority inheritance is used, then the prio_ceiling should be set to ILLEGAL_ELEM. The prio_ceiling MUST be unique (no task should have this as its base priority). |
Get mutex owner This returns the task id of the owner of a specified mutex.
This is an instantaneous snapshot of the state of the mutex. Due to preemption, the owner may have changed by the time the callee acts on this information. Example:
tid_t tmp; tmp = mutex_owner( m); // M has been initialized previously do_other_stuff(); if (tmp == other_task) do_more_stuff(); // the owner of m may have changed.
Calling Context:
Lock mutex.
This is used to exclusively lock a mutex by a task. The locking behavior depends on the mutex protocol that has been configured. If the specified mutex is not locked, it is locked by the calling task at the end of the call, and a SUCCESS is returned. Attempts by a task to lock a mutex that it already holds also return SUCCESS. Attempts by an ISR to lock a mutex will result in an error code of ERR_LOCK_ISR, since ISRs are not allowed to lock mutexes. If a task already has locked TIROS_MAX_MUTEXES mutexes, then ERR_FULL will be returned, as it is not allowed to lock any more mutexes. Attempts to lock a mutex owned by a different task will result in blocking. If the O_NONBLOCKING option is specified, then the ERR_WOULDBLOCK error code is returned, else the task is made to wait until the timeout, when ERR_TIMEOUT is returned. If the task is explicitly resumed during its wait, it receives the ERR_RESUMED code.
Calling Context:
m | Pointer to mutex | |
timeout | Timeout. This can be 0 for infinite timeout. | |
options | Combination of [O_RELATIVE_TIME | O_NONBLOCKING]. |
Unlock Mutex.
Calling Context:
m | Pointer to mutex. |