589 lines
19 KiB
C
589 lines
19 KiB
C
/*
|
|
* FreeRTOS V202111.00
|
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
* this software and associated documentation files (the "Software"), to deal in
|
|
* the Software without restriction, including without limitation the rights to
|
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
* subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*
|
|
* https://www.FreeRTOS.org
|
|
* https://github.com/FreeRTOS
|
|
*
|
|
*/
|
|
/*! @file mutex_utest.c */
|
|
|
|
#include "../queue_utest_common.h"
|
|
|
|
/* Queue includes */
|
|
#include "FreeRTOS.h"
|
|
#include "FreeRTOSConfig.h"
|
|
#include "semphr.h"
|
|
#include "mock_fake_port.h"
|
|
|
|
/* ============================ GLOBAL VARIABLES =========================== */
|
|
static SemaphoreHandle_t xSemaphoreHandleStatic = NULL;
|
|
|
|
/* ========================== CALLBACK FUNCTIONS =========================== */
|
|
|
|
/* ============================= Unity Fixtures ============================= */
|
|
|
|
void setUp( void )
|
|
{
|
|
commonSetUp();
|
|
}
|
|
|
|
void tearDown( void )
|
|
{
|
|
commonTearDown();
|
|
}
|
|
|
|
void suiteSetUp()
|
|
{
|
|
commonSuiteSetUp();
|
|
}
|
|
|
|
int suiteTearDown( int numFailures )
|
|
{
|
|
return commonSuiteTearDown( numFailures );
|
|
}
|
|
|
|
/* ========================== Helper functions =========================== */
|
|
|
|
/* ========================== Test Cases =========================== */
|
|
|
|
|
|
/**
|
|
* @brief Test xSemaphoreCreateMutex where the call to malloc fails
|
|
* @coverage xQueueCreateMutex
|
|
*/
|
|
void test_macro_xSemaphoreCreateMutex_malloc_fail( void )
|
|
{
|
|
UnityMalloc_MakeMallocFailAfterCount( 0 );
|
|
|
|
SemaphoreHandle_t xSemaphore = INVALID_PTR;
|
|
|
|
xSemaphore = xSemaphoreCreateMutex();
|
|
|
|
/* validate returned semaphore handle */
|
|
TEST_ASSERT_EQUAL( NULL, xSemaphore );
|
|
}
|
|
|
|
/**
|
|
* @brief Test xSemaphoreCreateMutex
|
|
* @details Create a mutex using xSemaphoreCreateMutex
|
|
* @coverage xQueueCreateMutex
|
|
*/
|
|
void test_macro_xSemaphoreCreateMutex_success( void )
|
|
{
|
|
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
|
|
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
|
|
|
|
/* validate returned semaphore handle */
|
|
TEST_ASSERT_NOT_EQUAL( NULL, xSemaphore );
|
|
|
|
TEST_ASSERT_EQUAL( QUEUE_T_SIZE, getLastMallocSize() );
|
|
|
|
TEST_ASSERT_EQUAL( B_SEMPHR_AVAILABLE, uxSemaphoreGetCount( xSemaphore ) );
|
|
|
|
vSemaphoreDelete( xSemaphore );
|
|
}
|
|
|
|
/**
|
|
* @brief Test xSemaphoreCreateMutexStatic with a null buffer
|
|
* @coverage xQueueCreateMutexStatic
|
|
*/
|
|
void test_macro_xSemaphoreCreateMutexStatic_nullptr( void )
|
|
{
|
|
SemaphoreHandle_t xSemaphore = INVALID_PTR;
|
|
|
|
/* Expect that xQueueCreate will assert due to the NULL buffer */
|
|
fakeAssertExpectFail();
|
|
|
|
xSemaphore = xSemaphoreCreateMutexStatic( NULL );
|
|
|
|
/* Check that configASSERT was called twice */
|
|
fakeAssertVerifyNumAssertsAndClear( 2 );
|
|
|
|
TEST_ASSERT_EQUAL( NULL, xSemaphore );
|
|
TEST_ASSERT_EQUAL( 0, getLastMallocSize() );
|
|
}
|
|
|
|
/**
|
|
* @brief Test xSemaphoreCreateMutexStatic with a valid buffer.
|
|
* @details Create a semaphore using xSemaphoreCreateMutexStatic
|
|
* @coverage xQueueCreateMutexStatic
|
|
*/
|
|
void test_macro_xSemaphoreCreateMutexStatic_success( void )
|
|
{
|
|
SemaphoreHandle_t xSemaphore = NULL;
|
|
StaticSemaphore_t xSemaphoreBuffer;
|
|
|
|
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
|
|
|
|
xSemaphore = xSemaphoreCreateMutexStatic( &xSemaphoreBuffer );
|
|
|
|
/* Check that no call to malloc occurred */
|
|
TEST_ASSERT_EQUAL( 0, getLastMallocSize() );
|
|
|
|
TEST_ASSERT_EQUAL( B_SEMPHR_AVAILABLE, uxSemaphoreGetCount( xSemaphore ) );
|
|
|
|
vSemaphoreDelete( xSemaphore );
|
|
}
|
|
|
|
/**
|
|
* @brief Test xSemaphoreTake with a Mutex
|
|
* @details Create a mutex using xSemaphoreCreateMutex
|
|
* and verify that an immediate call to xSemaphoreTake succeeds.
|
|
* @coverage xQueueSemaphoreTake
|
|
*/
|
|
void test_macro_xSemaphoreTake_success( void )
|
|
{
|
|
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
|
|
|
|
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
|
|
|
|
/* validate returned semaphore handle */
|
|
TEST_ASSERT_NOT_EQUAL( NULL, xSemaphore );
|
|
|
|
TEST_ASSERT_EQUAL( QUEUE_T_SIZE, getLastMallocSize() );
|
|
|
|
pvTaskIncrementMutexHeldCount_IgnoreAndReturn( NULL );
|
|
|
|
/* Verify that an immediate xSemaphoreTake operation succeeds */
|
|
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTake( xSemaphore, 0 ) );
|
|
|
|
vSemaphoreDelete( xSemaphore );
|
|
}
|
|
|
|
/**
|
|
* @brief Test xSemaphoreGive with xSemaphoreCreateMutex
|
|
* @details Create a mutex using xSemaphoreCreateMutex
|
|
* and verify that an immediate call to xSemaphoreGive fails.
|
|
* @coverage xQueueGenericSend
|
|
*/
|
|
void test_macro_xSemaphoreGive_fail( void )
|
|
{
|
|
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
|
|
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
|
|
|
|
/* validate returned semaphore handle */
|
|
TEST_ASSERT_NOT_EQUAL( NULL, xSemaphore );
|
|
|
|
TEST_ASSERT_EQUAL( QUEUE_T_SIZE, getLastMallocSize() );
|
|
|
|
/* Verify that an immediate xSemaphoreGive operation fails */
|
|
TEST_ASSERT_EQUAL( pdFALSE, xSemaphoreGive( xSemaphore ) );
|
|
|
|
vSemaphoreDelete( xSemaphore );
|
|
}
|
|
|
|
/**
|
|
* @brief Test xSemaphoreGive and xSemaphoreTake with xSemaphoreCreateMutex
|
|
* @details Create a mutex using xSemaphoreCreateMutex
|
|
* and verify that an immediate call to xSemaphoreGive succeeds and a subsequent
|
|
* call to xSemaphoreTake succeeds.
|
|
* @coverage xQueueGenericSend xQueueSemaphoreTake
|
|
*/
|
|
void test_macro_xSemaphoreGive_xSemaphoreTake_success( void )
|
|
{
|
|
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
|
|
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
|
|
|
|
/* validate returned semaphore handle */
|
|
TEST_ASSERT_NOT_EQUAL( NULL, xSemaphore );
|
|
|
|
TEST_ASSERT_EQUAL( QUEUE_T_SIZE, getLastMallocSize() );
|
|
|
|
pvTaskIncrementMutexHeldCount_ExpectAndReturn( 0 );
|
|
|
|
/* Verify that an immediate xSemaphoreTake operation succeeds */
|
|
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTake( xSemaphore, 0 ) );
|
|
|
|
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
|
|
|
|
/* Verify that a subsequent xSemaphoreGive operation succeeds */
|
|
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreGive( xSemaphore ) );
|
|
|
|
vSemaphoreDelete( xSemaphore );
|
|
}
|
|
|
|
/**
|
|
* @brief Test xSemaphoreGive multiple times on a Mutex.
|
|
* @details Create a mutex using xSemaphoreCreateMutex
|
|
* and verify that an immediate call to xSemaphoreGive succeeds and a subsequent
|
|
* call to xSemaphoreGive fails.
|
|
* @coverage xQueueGenericSend
|
|
*/
|
|
void test_macro_xSemaphoreGive_multiple_Mutex_fail( void )
|
|
{
|
|
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
|
|
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
|
|
|
|
/* validate returned semaphore handle */
|
|
TEST_ASSERT_NOT_EQUAL( NULL, xSemaphore );
|
|
|
|
TEST_ASSERT_EQUAL( QUEUE_T_SIZE, getLastMallocSize() );
|
|
|
|
pvTaskIncrementMutexHeldCount_ExpectAndReturn( 0 );
|
|
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
|
|
|
|
xSemaphoreTake( xSemaphore, 0 );
|
|
|
|
/* Verify that the first xSemaphoreGive call succeeds */
|
|
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreGive( xSemaphore ) );
|
|
|
|
/* Verify that a second xSemaphoreGive call fails */
|
|
TEST_ASSERT_EQUAL( pdFALSE, xSemaphoreGive( xSemaphore ) );
|
|
|
|
vSemaphoreDelete( xSemaphore );
|
|
}
|
|
|
|
/**
|
|
* @brief Test xSemaphoreTake multiple times on a Mutex.
|
|
* @details Create a Mutex using xSemaphoreCreateMutex,
|
|
* verify that an immediate call to xSemaphoreTake succeeds, a subsequent
|
|
* call to xSemaphoreGive succeds, but a second call to xSemaphoreGive fails.
|
|
* @coverage xQueueSemaphoreTake
|
|
*/
|
|
void test_macro_xSemaphoreTake_multiple_Mutex_fail( void )
|
|
{
|
|
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
|
|
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
|
|
|
|
/* validate returned semaphore handle */
|
|
TEST_ASSERT_NOT_EQUAL( NULL, xSemaphore );
|
|
|
|
TEST_ASSERT_EQUAL( QUEUE_T_SIZE, getLastMallocSize() );
|
|
|
|
pvTaskIncrementMutexHeldCount_ExpectAndReturn( 0 );
|
|
|
|
/* Verify that an immediate xSemaphoreTake operation succeeds */
|
|
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTake( xSemaphore, 0 ) );
|
|
|
|
/* Verify that the second xSemaphoreTake operation fails */
|
|
TEST_ASSERT_EQUAL( pdFALSE, xSemaphoreTake( xSemaphore, 0 ) );
|
|
|
|
vSemaphoreDelete( xSemaphore );
|
|
}
|
|
|
|
/**
|
|
* @brief Test uxSemaphoreGetCount with a Mutex
|
|
* @details Create a Mutex using xSemaphoreCreateMutex.
|
|
* validate the return value of uxSemaphoreGetCount(),
|
|
* call xSemaphoreTake() and validate the return value of uxSemaphoreGetCount()
|
|
* @coverage uxQueueMessagesWaiting
|
|
*/
|
|
void test_macro_uxSemaphoreGetCount_Mutex( void )
|
|
{
|
|
SemaphoreHandle_t xSemaphore = NULL;
|
|
|
|
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
|
|
|
|
pvTaskIncrementMutexHeldCount_ExpectAndReturn( 0 );
|
|
|
|
xSemaphore = xSemaphoreCreateMutex();
|
|
|
|
TEST_ASSERT_EQUAL( B_SEMPHR_AVAILABLE, uxSemaphoreGetCount( xSemaphore ) );
|
|
|
|
xSemaphoreTake( xSemaphore, 0 );
|
|
|
|
TEST_ASSERT_EQUAL( B_SEMPHR_TAKEN, uxSemaphoreGetCount( xSemaphore ) );
|
|
|
|
vSemaphoreDelete( xSemaphore );
|
|
}
|
|
|
|
/**
|
|
* @brief Test xSemaphoreGetMutexHolder with an invalid (null) SemaphoreHandle_t
|
|
* @coverage xQueueGetMutexHolder
|
|
*/
|
|
void test_macro_xSemaphoreGetMutexHolder_NULL( void )
|
|
{
|
|
/* This previously caused a segfault, but I patched queue.c */
|
|
EXPECT_ASSERT_BREAK( xSemaphoreGetMutexHolder( NULL ) );
|
|
}
|
|
|
|
/**
|
|
* @brief Test xSemaphoreGetMutexHolder with a handle of a binary semaphore
|
|
* @details Verify that xSemaphoreGetMutexHolder returns NULL when given a handle to a binary semaphore rather than a mutex.
|
|
* @coverage xQueueGetMutexHolder
|
|
*/
|
|
void test_macro_xSemaphoreGetMutexHolder_binary_semaphore( void )
|
|
{
|
|
SemaphoreHandle_t xSemaphore = xSemaphoreCreateBinary();
|
|
|
|
TEST_ASSERT_EQUAL( B_SEMPHR_TAKEN, uxSemaphoreGetCount( xSemaphore ) );
|
|
|
|
TEST_ASSERT_EQUAL( NULL, xSemaphoreGetMutexHolder( xSemaphore ) );
|
|
|
|
vSemaphoreDelete( xSemaphore );
|
|
}
|
|
|
|
/**
|
|
* @brief Test xSemaphoreGetMutexHolder with a valid SemaphoreHandle_t
|
|
* @coverage xQueueGetMutexHolder
|
|
*/
|
|
void test_macro_xSemaphoreGetMutexHolder_Mutex( void )
|
|
{
|
|
TaskHandle_t xMutexHolder = ( void * ) ( BaseType_t ) getNextMonotonicTestValue();
|
|
|
|
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
|
|
|
|
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
|
|
|
|
pvTaskIncrementMutexHeldCount_ExpectAndReturn( xMutexHolder );
|
|
|
|
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTake( xSemaphore, 0 ) );
|
|
|
|
TEST_ASSERT_EQUAL( xMutexHolder, xSemaphoreGetMutexHolder( xSemaphore ) );
|
|
|
|
vSemaphoreDelete( xSemaphore );
|
|
}
|
|
|
|
/**
|
|
* @brief Test xSemaphoreGetMutexHolderFromISR with an invalid (null) SemaphoreHandle_t
|
|
* @coverage xQueueGetMutexHolderFromISR
|
|
*/
|
|
void test_macro_xSemaphoreGetMutexHolderFromISR_Mutex_NULL( void )
|
|
{
|
|
EXPECT_ASSERT_BREAK( xSemaphoreGetMutexHolderFromISR( NULL ) );
|
|
}
|
|
|
|
/**
|
|
* @brief Test xSemaphoreGetMutexHolderFromISR with a handle of a binary semaphore
|
|
* @details Verify that xSemaphoreGetMutexHolderFromISR returns NULL when given a handle to a binary semaphore rather than a mutex.
|
|
* @coverage xQueueGetMutexHolderFromISR
|
|
*/
|
|
void test_macro_xSemaphoreGetMutexHolderFromISR_binary_semaphore( void )
|
|
{
|
|
SemaphoreHandle_t xSemaphore = xSemaphoreCreateBinary();
|
|
|
|
TEST_ASSERT_EQUAL( B_SEMPHR_TAKEN, uxSemaphoreGetCount( xSemaphore ) );
|
|
|
|
TEST_ASSERT_EQUAL( NULL, xSemaphoreGetMutexHolderFromISR( xSemaphore ) );
|
|
|
|
vSemaphoreDelete( xSemaphore );
|
|
}
|
|
|
|
/**
|
|
* @brief Test xSemaphoreGetMutexHolderFromISR with a valid SemaphoreHandle_t
|
|
* @coverage xQueueGetMutexHolderFromISR
|
|
*/
|
|
void test_macro_xSemaphoreGetMutexHolderFromISR_Mutex( void )
|
|
{
|
|
TaskHandle_t xMutexHolder = ( void * ) ( BaseType_t ) getNextMonotonicTestValue();
|
|
|
|
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
|
|
|
|
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
|
|
|
|
pvTaskIncrementMutexHeldCount_ExpectAndReturn( xMutexHolder );
|
|
|
|
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTake( xSemaphore, 0 ) );
|
|
|
|
TEST_ASSERT_EQUAL( xMutexHolder, xSemaphoreGetMutexHolderFromISR( xSemaphore ) );
|
|
|
|
vSemaphoreDelete( xSemaphore );
|
|
}
|
|
|
|
/**
|
|
* @brief Test xSemaphoreGiveFromISR with a Mutex that has an owner.
|
|
* @details Verify that xSemaphoreGiveFromISR configASSERTs when an owned mutex is given as the xSemaphore argument.
|
|
* @coverage xQueueGiveFromISR
|
|
*/
|
|
void test_macro_xSemaphoreGiveFromISR_mutex_owned( void )
|
|
{
|
|
TaskHandle_t xMutexHolder = ( void * ) ( BaseType_t ) getNextMonotonicTestValue();
|
|
|
|
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
|
|
|
|
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
|
|
|
|
/* Setup mocks for xSemaphoretake */
|
|
pvTaskIncrementMutexHeldCount_ExpectAndReturn( xMutexHolder );
|
|
vFakePortAssertIfInterruptPriorityInvalid_Expect();
|
|
|
|
xSemaphoreTake( xSemaphore, 0 );
|
|
|
|
/* Expect that xSemaphoreGiveFromISR will assert due to the mutex usage */
|
|
fakeAssertExpectFail();
|
|
|
|
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreGiveFromISR( xSemaphore, NULL ) );
|
|
|
|
TEST_ASSERT_EQUAL( true, fakeAssertGetFlagAndClear() );
|
|
|
|
TEST_ASSERT_EQUAL( B_SEMPHR_AVAILABLE, uxSemaphoreGetCount( xSemaphore ) );
|
|
|
|
vSemaphoreDelete( xSemaphore );
|
|
}
|
|
|
|
/**
|
|
* @brief Test xSemaphoreGiveFromISR with a Mutex that has a NULL owner.
|
|
* @details Verify that xSemaphoreGiveFromISR does not configASSERT when a mutex with a NULL owner is given in the xSemaphore argument.
|
|
* @coverage xQueueGiveFromISR
|
|
*/
|
|
void test_macro_xSemaphoreGiveFromISR_mutex_not_owned( void )
|
|
{
|
|
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
|
|
|
|
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
|
|
|
|
/* Setup mocks for xSemaphoretake */
|
|
pvTaskIncrementMutexHeldCount_ExpectAndReturn( NULL );
|
|
vFakePortAssertIfInterruptPriorityInvalid_Expect();
|
|
|
|
xSemaphoreTake( xSemaphore, 0 );
|
|
|
|
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreGiveFromISR( xSemaphore, NULL ) );
|
|
|
|
TEST_ASSERT_EQUAL( B_SEMPHR_AVAILABLE, uxSemaphoreGetCount( xSemaphore ) );
|
|
|
|
vSemaphoreDelete( xSemaphore );
|
|
}
|
|
|
|
/**
|
|
* @brief Test xSemaphoreTake in blocking mode on an already owned mutex.
|
|
* @details Test xSemaphoreTake on a mutex owned by another task where the owning task has lower priority.
|
|
* @coverage xQueueSemaphoreTake prvGetDisinheritPriorityAfterTimeout
|
|
*/
|
|
void test_macro_xSemaphoreTake_blocking_mutex_inherit_timeout( void )
|
|
{
|
|
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
|
|
|
|
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
|
|
|
|
BaseType_t xFakeMutexHolder = getNextMonotonicTestValue();
|
|
|
|
/* Return a test value from the call to pvTaskIncrementMutexHeldCount */
|
|
pvTaskIncrementMutexHeldCount_ExpectAndReturn( ( void * ) xFakeMutexHolder );
|
|
|
|
/* Take the mutex */
|
|
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTake( xSemaphore, 0 ) );
|
|
|
|
for( int i = 0; i < TICKS_TO_WAIT; i++ )
|
|
{
|
|
/* Return pdTRUE to signify that priority inheritance occurred */
|
|
xTaskPriorityInherit_ExpectAndReturn( ( void * ) xFakeMutexHolder, pdTRUE );
|
|
}
|
|
|
|
vTaskPriorityDisinheritAfterTimeout_Expect( ( void * ) ( BaseType_t ) getLastMonotonicTestValue(), tskIDLE_PRIORITY );
|
|
|
|
TEST_ASSERT_EQUAL( pdFALSE, xSemaphoreTake( xSemaphore, TICKS_TO_WAIT ) );
|
|
|
|
TEST_ASSERT_EQUAL( TICKS_TO_WAIT, td_task_getYieldCount() );
|
|
|
|
TEST_ASSERT_EQUAL( TICKS_TO_WAIT, td_task_getCount_vPortYieldWithinAPI() );
|
|
|
|
vSemaphoreDelete( xSemaphore );
|
|
}
|
|
|
|
/**
|
|
* @brief Test xSemaphoreTake in blocking mode on an already owned mutex.
|
|
* @details Test xSemaphoreTake on a mutex owned by another task with another high priority task waiting and the current task timing out.
|
|
* @coverage xQueueSemaphoreTake prvGetDisinheritPriorityAfterTimeout
|
|
*/
|
|
void test_macro_xSemaphoreTake_blocking_mutex_inherit_timeout_high_prio_waiting( void )
|
|
{
|
|
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
|
|
|
|
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
|
|
|
|
TaskHandle_t xFakeMutexHolder = ( TaskHandle_t ) ( ( uint64_t ) 0 + getNextMonotonicTestValue() );
|
|
|
|
/* Return a test value from the call to pvTaskIncrementMutexHeldCount */
|
|
pvTaskIncrementMutexHeldCount_ExpectAndReturn( xFakeMutexHolder );
|
|
|
|
/* Take the mutex */
|
|
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTake( xSemaphore, 0 ) );
|
|
|
|
/* Insert an item into the event list */
|
|
td_task_setFakeTaskPriority( DEFAULT_PRIORITY + 1 );
|
|
td_task_addFakeTaskWaitingToReceiveFromQueue( xSemaphore );
|
|
|
|
for( int i = 0; i < TICKS_TO_WAIT; i++ )
|
|
{
|
|
/* Return pdTRUE to signify that priority inheritance occurred */
|
|
xTaskPriorityInherit_ExpectAndReturn( xFakeMutexHolder, pdTRUE );
|
|
}
|
|
|
|
vTaskPriorityDisinheritAfterTimeout_Expect( xFakeMutexHolder, DEFAULT_PRIORITY + 1 );
|
|
|
|
|
|
TEST_ASSERT_EQUAL( pdFALSE, xSemaphoreTake( xSemaphore, TICKS_TO_WAIT ) );
|
|
|
|
TEST_ASSERT_EQUAL( TICKS_TO_WAIT + 1, td_task_getYieldCount() );
|
|
|
|
TEST_ASSERT_EQUAL( TICKS_TO_WAIT + 1, td_task_getCount_YieldFromTaskResumeAll() );
|
|
|
|
vSemaphoreDelete( xSemaphore );
|
|
}
|
|
|
|
/**
|
|
* @brief Callback for test_macro_xSemaphoreTake_blocking_mutex_inherit_disinherit
|
|
*/
|
|
static BaseType_t xSemaphoreTake_blocking_xTaskResumeAllStub( int cmock_num_calls )
|
|
{
|
|
BaseType_t xReturnValue = td_task_xTaskResumeAllStub( cmock_num_calls );
|
|
|
|
if( cmock_num_calls == NUM_CALLS_TO_INTERCEPT )
|
|
{
|
|
TEST_ASSERT_TRUE( xSemaphoreGive( xSemaphoreHandleStatic ) );
|
|
}
|
|
|
|
return xReturnValue;
|
|
}
|
|
|
|
/**
|
|
* @brief Test priority inheritance during a successful blocking call to xSemaphoreTake
|
|
* @coverage xQueueSemaphoreTake
|
|
*/
|
|
void test_macro_xSemaphoreTake_blocking_mutex_inherit_disinherit( void )
|
|
{
|
|
xTaskPriorityDisinherit_ExpectAndReturn( NULL, pdFALSE );
|
|
|
|
SemaphoreHandle_t xSemaphore = xSemaphoreCreateMutex();
|
|
|
|
xSemaphoreHandleStatic = xSemaphore;
|
|
|
|
TaskHandle_t xFakeMutexHolder = ( TaskHandle_t ) ( ( uint64_t ) 0 + getNextMonotonicTestValue() );
|
|
|
|
xTaskResumeAll_Stub( &xSemaphoreTake_blocking_xTaskResumeAllStub );
|
|
|
|
/* Return a test value from the call to pvTaskIncrementMutexHeldCount */
|
|
pvTaskIncrementMutexHeldCount_ExpectAndReturn( xFakeMutexHolder );
|
|
|
|
/* Take the mutex */
|
|
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTake( xSemaphore, 0 ) );
|
|
|
|
for( int i = 0; i < NUM_CALLS_TO_INTERCEPT + 1; i++ )
|
|
{
|
|
/* Return pdTRUE to signify that priority inheritance occurred */
|
|
xTaskPriorityInherit_ExpectAndReturn( xFakeMutexHolder, pdTRUE );
|
|
}
|
|
|
|
xTaskPriorityDisinherit_ExpectAndReturn( xFakeMutexHolder, pdTRUE );
|
|
|
|
/* Return a test value from the call to pvTaskIncrementMutexHeldCount */
|
|
pvTaskIncrementMutexHeldCount_ExpectAndReturn( xFakeMutexHolder );
|
|
|
|
TEST_ASSERT_EQUAL( pdTRUE, xSemaphoreTake( xSemaphore, TICKS_TO_WAIT ) );
|
|
|
|
TEST_ASSERT_EQUAL( NUM_CALLS_TO_INTERCEPT + 2, td_task_getYieldCount() );
|
|
|
|
TEST_ASSERT_EQUAL( NUM_CALLS_TO_INTERCEPT + 2, td_task_getCount_vPortYieldWithinAPI() );
|
|
|
|
vSemaphoreDelete( xSemaphore );
|
|
}
|