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).
RETURNS
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.
RETURNS
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.
RETURNS
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.
RETURNS
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.