Mutexes
A mutex is a synchronization object that provides a mutually exclusive access to a resource. For example, to prevent two threads
from writing to shared memory at the same time, each thread acquires ownership of a mutex before executing the code that accesses
the memory. After writing to the shared memory, the thread releases the mutex.
A thread can request ownership of a mutex by using MUTEX_Acquire(). If the mutex does not have an owner, the calling thread will not
be blocked, but if the mutex is already owned by a different thread, the thread will be blocked until the mutex is released by the
owning thread using MUTEX_Release().
After a thread obtains ownership of a mutex, it can specify the same mutex within subsequent calls to acquire ownership of the mutex
without being blocked, but the thread must release the mutex once for each time the mutex was acquired.
A mutex supports priority inheritance so that when a thread with higher priority is blocked while waiting to acquire ownership of
the mutex, the kernel will temporarily give the owner of the mutex the same priority of the blocked thread. Once the mutex
has been released, the original owning thread will return back to it's original priority.
Basic Usage
The code snippet below illustrates how to allocate and create a mutex.
#include "Kernel/kernel_mutex.h"
#include <assert.h>
static MUTEX mutex1; /* Allocate a mutex */
void APP_Example(void)
{
STATUS status;
status = MUTEX_Create(&mutex1, /* Create and initialize the mutex */
"Mutex1", /* A name for the mutex (debugging purposes) */
FALSE); /* Not the initial owner */
assert(status == SUCCESS);
}
The snippet below uses a mutex to create an area that can only be accessed by a single thread at any given point in time.
#include "Kernel/kernel_mutex.h"
void APP_Example(void)
{
STATUS status;
status = MUTEX_Acquire(&mutex1, INFINITE); /* Wait indefinitely to acquire the mutex */
if (status == SUCCESS) { /* Mutex successfully acquired? */
/* ... Single thread access here ... */
MUTEX_Release(&mutex1); /* Release the mutex */
}
}
API Reference
STATUS MUTEX_Create(MUTEX* mutex, const CHAR* name, BOOLEAN owner)
Creates and initializes a mutex.
PARAMETERS
mutex | A pointer to a caller allocated mutex to be initialized. |
name | A pointer to a NULL terminated string that represents a name for the mutex. |
owner | Use TRUE to have the caller initially be the owner of the mutex (already acquired). |
SUCCESS | The mutex has been created and initialized. |
ERR_NULLREFERENCE | The argument 'mutex' was found to be NULL. |
ERR_INVALIDCONTEXT | The operation is not supported from the context of an interrupt service routine (ISR). |
ERR_ALREADYINITIALIZED | The specified mutex has already been created and initialized. |
STATUS MUTEX_Destroy(MUTEX* mutex)
Destroys and removes a mutex from the kernel. Any threads that happen to be waiting to acquire the mutex will be released with the
ERR_DESTROYED status code.
PARAMETERS
mutex | A pointer to a mutex to be destroyed. |
SUCCESS | The mutex has been destroyed and removed from the kernel. |
ERR_NULLREFERENCE | The argument 'mutex' was found to be NULL. |
ERR_INVALIDCONTEXT | The operation is not supported from the context of an interrupt service routine (ISR). |
ERR_NOTINITIALIZED | The specified mutex has not been created and initialized. |
STATUS MUTEX_Acquire(MUTEX* mutex, UINT32 timeout)
Acquires ownership of a mutex.
PARAMETERS
mutex | A pointer to the mutex to be acquired. |
timeout | The maximum amount of time, in kernel ticks, to block and wait to acquire ownership of the mutex. Use '0' to
return immediately without blocking or use 'INFINITE' to block indefinitely. |
SUCCESS | The calling thread has acquired ownership of the mutex. |
ERR_NULLREFERENCE | The argument 'mutex' was found to be NULL. |
ERR_INVALIDCONTEXT | The operation is not supported from the context of an interrupt service routine (ISR). |
ERR_NOTINITIALIZED | The specified mutex has not been created and initialized. |
ERR_TIMEOUT | The specified amount of time has elapsed while waiting to acquire ownership of the mutex. |
ERR_DESTROYED | The operation failed because the mutex has been destroyed. |
ERR_ABORTED | The caller is unable to block because it has been aborted. |
REMARKS
Only causes a context switch to occur if the mutex happens to be owned by a different thread. |
MUTEX_Acquire() can be called multiple times, but the mutex will require the same number of MUTEX_Release() calls to
completely release ownership. |
STATUS MUTEX_Release(MUTEX* mutex)
Releases ownership of a mutex.
PARAMETERS
mutex | A pointer to the mutex to have ownership released. |
SUCCESS | The mutex has been released. |
ERR_NULLREFERENCE | The argument 'mutex' was found to be NULL. |
ERR_INVALIDCONTEXT | The operation is not supported from the context of an interrupt service routine (ISR). |
ERR_NOTINITIALIZED | The specified mutex has not been created and initialized. |
ERR_NOTOWNER | The calling thread is not the owner, but only the owner is allowed to release the mutex. |
REMARKS
If there were multiple calls to MUTEX_Acquire() by the owning thread, the mutex will not be released until the same number
of MUTEX_Release() calls have been made. |