This is file "mutex.c".
NEW: Fixed the declaration of "pxOwner".
//============================================================================== // Copyright (c) 2007-2009, Isaac Marino Bavaresco // All rights reserved // isaacbavaresco@yahoo.com.br //============================================================================== #include "FreeRTOS.h" #include "list.h" #include "task.h" //============================================================================== typedef struct { xList xTasksWaitingToTake; xTaskHandle pxOwner; size_t uxCount; } xMUTEX; //============================================================================== typedef xMUTEX *xMutexHandle; //============================================================================== xMutexHandle xMutexCreate( void ) { xMUTEX *pxNewMutex; pxNewMutex = pvPortMalloc( sizeof( xMUTEX )); if( pxNewMutex != NULL ) { pxNewMutex->pxOwner = NULL; pxNewMutex->uxCount = 0; vListInitialise( &( pxNewMutex->xTasksWaitingToTake ) ); } return pxNewMutex; } //============================================================================== signed portBASE_TYPE xMutexTake( xMutexHandle pxMutex, portTickType xTicksToWait ) { portENTER_CRITICAL(); if( pxMutex->pxOwner == xTaskGetCurrentTaskHandle() ) { pxMutex->uxCount++; portEXIT_CRITICAL(); return pdTRUE; } if(( xTicksToWait > ( portTickType ) 0 ) && ( pxMutex->pxOwner != NULL )) { vTaskPlaceOnEventList( &( pxMutex->xTasksWaitingToTake ), xTicksToWait ); taskYIELD(); if( pxMutex->pxOwner == xTaskGetCurrentTaskHandle() ) { pxMutex->uxCount = 1; portEXIT_CRITICAL(); return pdTRUE; } else { portEXIT_CRITICAL(); return pdFALSE; } } if( pxMutex->pxOwner == NULL ) { pxMutex->pxOwner = xTaskGetCurrentTaskHandle(); pxMutex->uxCount = 1; portEXIT_CRITICAL(); return pdTRUE; } portEXIT_CRITICAL(); return pdFALSE; } //============================================================================== signed portBASE_TYPE xMutexGive( xMutexHandle pxMutex, portBASE_TYPE Release ) { portENTER_CRITICAL(); if( pxMutex->pxOwner != xTaskGetCurrentTaskHandle() ) { portEXIT_CRITICAL(); return pdFALSE; } if( Release ) pxMutex->uxCount = 0; else { if( --pxMutex->uxCount != 0 ) { portEXIT_CRITICAL(); return pdFALSE; } } if( !listLIST_IS_EMPTY( &pxMutex->xTasksWaitingToTake )) { pxMutex->pxOwner = (xTaskHandle)listGET_OWNER_OF_HEAD_ENTRY( (&pxMutex->xTasksWaitingToTake) ); pxMutex->uxCount = 1; if( xTaskRemoveFromEventList( &pxMutex->xTasksWaitingToTake ) == pdTRUE ) taskYIELD(); } else pxMutex->pxOwner = NULL; portEXIT_CRITICAL(); return pdTRUE; } //============================================================================== signed portBASE_TYPE xDoIOwnTheMutex( xMutexHandle pxMutex ) { portBASE_TYPE c; portENTER_CRITICAL(); c = pxMutex->pxOwner == xTaskGetCurrentTaskHandle(); portEXIT_CRITICAL(); return c; } //==============================================================================