From 51a1598e4e0281de8b8d54467747af460478eadc Mon Sep 17 00:00:00 2001 From: Bhoomika R S Date: Wed, 12 Feb 2025 14:57:03 +0530 Subject: [PATCH 1/3] Add instruction to suppress SIGUSR1 in Posix with LLDB debugger (#1245) While using the macOS default LLDB debugger, a call to vTaskEndScheduler results in an unhandled SIGUSR1 (aka SIGRESUME) when restoring the scheduler thread's signals with pthread_sigmask. This crashes the program. Added instructions in portable/ThirdParty/GCC/Posix/port.c to suppress SIGUSR1 to prevent LLDB debugger interference when exiting xPortStartScheduler Thanks to: @johnboiles for pointing it out in #1224 --- portable/ThirdParty/GCC/Posix/port.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/portable/ThirdParty/GCC/Posix/port.c b/portable/ThirdParty/GCC/Posix/port.c index 5dc7f45f8..ff386ac9f 100644 --- a/portable/ThirdParty/GCC/Posix/port.c +++ b/portable/ThirdParty/GCC/Posix/port.c @@ -48,6 +48,11 @@ * stdio (printf() and friends) should be called from a single task * only or serialized with a FreeRTOS primitive such as a binary * semaphore or mutex. +* +* Note: When using LLDB (the default debugger on macOS) with this port, +* suppress SIGUSR1 to prevent debugger interference. This can be +* done by adding the following line to ~/.lldbinit: +* `process handle SIGUSR1 -n true -p true -s false` *----------------------------------------------------------*/ #ifdef __linux__ #define _GNU_SOURCE From 29e817b70eccb4cb7cf9131ea0484b5b19c3016f Mon Sep 17 00:00:00 2001 From: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Date: Wed, 12 Feb 2025 20:57:18 +0530 Subject: [PATCH 2/3] Include current task runtime in ulTaskGetRunTimeCounter (#1234) * Include current task runtime in ulTaskGetRunTimeCounter Update ulTaskGetRunTimeCounter to include elapsed time since the last context switch when called for the currently running task. Previously, this time was not included in the calculation. Fixes #1202. Signed-off-by: Gaurav Aggarwal --- tasks.c | 88 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 70 insertions(+), 18 deletions(-) diff --git a/tasks.c b/tasks.c index 783f54810..def843fe6 100644 --- a/tasks.c +++ b/tasks.c @@ -6215,7 +6215,7 @@ static void prvCheckTasksWaitingTermination( void ) #if ( configGENERATE_RUN_TIME_STATS == 1 ) { - pxTaskStatus->ulRunTimeCounter = pxTCB->ulRunTimeCounter; + pxTaskStatus->ulRunTimeCounter = ulTaskGetRunTimeCounter( xTask ); } #else { @@ -8415,15 +8415,37 @@ TickType_t uxTaskResetEventItemValue( void ) configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) { TCB_t * pxTCB; + configRUN_TIME_COUNTER_TYPE ulTotalTime = 0, ulTimeSinceLastSwitchedIn = 0, ulTaskRunTime = 0; traceENTER_ulTaskGetRunTimeCounter( xTask ); pxTCB = prvGetTCBFromHandle( xTask ); configASSERT( pxTCB != NULL ); - traceRETURN_ulTaskGetRunTimeCounter( pxTCB->ulRunTimeCounter ); + taskENTER_CRITICAL(); + { + if( taskTASK_IS_RUNNING( pxTCB ) == pdTRUE ) + { + #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE + portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalTime ); + #else + ulTotalTime = portGET_RUN_TIME_COUNTER_VALUE(); + #endif - return pxTCB->ulRunTimeCounter; + #if ( configNUMBER_OF_CORES == 1 ) + ulTimeSinceLastSwitchedIn = ulTotalTime - ulTaskSwitchedInTime[ 0 ]; + #else + ulTimeSinceLastSwitchedIn = ulTotalTime - ulTaskSwitchedInTime[ pxTCB->xTaskRunState ]; + #endif + } + + ulTaskRunTime = pxTCB->ulRunTimeCounter + ulTimeSinceLastSwitchedIn; + } + taskEXIT_CRITICAL(); + + traceRETURN_ulTaskGetRunTimeCounter( ulTaskRunTime ); + + return ulTaskRunTime; } #endif /* if ( configGENERATE_RUN_TIME_STATS == 1 ) */ @@ -8434,11 +8456,17 @@ TickType_t uxTaskResetEventItemValue( void ) configRUN_TIME_COUNTER_TYPE ulTaskGetRunTimePercent( const TaskHandle_t xTask ) { TCB_t * pxTCB; - configRUN_TIME_COUNTER_TYPE ulTotalTime, ulReturn; + configRUN_TIME_COUNTER_TYPE ulTotalTime, ulReturn, ulTaskRunTime; traceENTER_ulTaskGetRunTimePercent( xTask ); - ulTotalTime = ( configRUN_TIME_COUNTER_TYPE ) portGET_RUN_TIME_COUNTER_VALUE(); + ulTaskRunTime = ulTaskGetRunTimeCounter( xTask ); + + #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE + portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalTime ); + #else + ulTotalTime = ( configRUN_TIME_COUNTER_TYPE ) portGET_RUN_TIME_COUNTER_VALUE(); + #endif /* For percentage calculations. */ ulTotalTime /= ( configRUN_TIME_COUNTER_TYPE ) 100; @@ -8449,7 +8477,7 @@ TickType_t uxTaskResetEventItemValue( void ) pxTCB = prvGetTCBFromHandle( xTask ); configASSERT( pxTCB != NULL ); - ulReturn = pxTCB->ulRunTimeCounter / ulTotalTime; + ulReturn = ulTaskRunTime / ulTotalTime; } else { @@ -8468,19 +8496,42 @@ TickType_t uxTaskResetEventItemValue( void ) configRUN_TIME_COUNTER_TYPE ulTaskGetIdleRunTimeCounter( void ) { - configRUN_TIME_COUNTER_TYPE ulReturn = 0; + configRUN_TIME_COUNTER_TYPE ulTotalTime = 0, ulTimeSinceLastSwitchedIn = 0, ulIdleTaskRunTime = 0; BaseType_t i; traceENTER_ulTaskGetIdleRunTimeCounter(); - for( i = 0; i < ( BaseType_t ) configNUMBER_OF_CORES; i++ ) + taskENTER_CRITICAL(); { - ulReturn += xIdleTaskHandles[ i ]->ulRunTimeCounter; + #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE + portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalTime ); + #else + ulTotalTime = portGET_RUN_TIME_COUNTER_VALUE(); + #endif + + for( i = 0; i < ( BaseType_t ) configNUMBER_OF_CORES; i++ ) + { + if( taskTASK_IS_RUNNING( xIdleTaskHandles[ i ] ) == pdTRUE ) + { + #if ( configNUMBER_OF_CORES == 1 ) + ulTimeSinceLastSwitchedIn = ulTotalTime - ulTaskSwitchedInTime[ 0 ]; + #else + ulTimeSinceLastSwitchedIn = ulTotalTime - ulTaskSwitchedInTime[ xIdleTaskHandles[ i ]->xTaskRunState ]; + #endif + } + else + { + ulTimeSinceLastSwitchedIn = 0; + } + + ulIdleTaskRunTime += ( xIdleTaskHandles[ i ]->ulRunTimeCounter + ulTimeSinceLastSwitchedIn ); + } } + taskEXIT_CRITICAL(); - traceRETURN_ulTaskGetIdleRunTimeCounter( ulReturn ); + traceRETURN_ulTaskGetIdleRunTimeCounter( ulIdleTaskRunTime ); - return ulReturn; + return ulIdleTaskRunTime; } #endif /* if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) */ @@ -8492,11 +8543,16 @@ TickType_t uxTaskResetEventItemValue( void ) { configRUN_TIME_COUNTER_TYPE ulTotalTime, ulReturn; configRUN_TIME_COUNTER_TYPE ulRunTimeCounter = 0; - BaseType_t i; traceENTER_ulTaskGetIdleRunTimePercent(); - ulTotalTime = portGET_RUN_TIME_COUNTER_VALUE() * configNUMBER_OF_CORES; + #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE + portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalTime ); + #else + ulTotalTime = ( configRUN_TIME_COUNTER_TYPE ) portGET_RUN_TIME_COUNTER_VALUE(); + #endif + + ulTotalTime *= configNUMBER_OF_CORES; /* For percentage calculations. */ ulTotalTime /= ( configRUN_TIME_COUNTER_TYPE ) 100; @@ -8504,11 +8560,7 @@ TickType_t uxTaskResetEventItemValue( void ) /* Avoid divide by zero errors. */ if( ulTotalTime > ( configRUN_TIME_COUNTER_TYPE ) 0 ) { - for( i = 0; i < ( BaseType_t ) configNUMBER_OF_CORES; i++ ) - { - ulRunTimeCounter += xIdleTaskHandles[ i ]->ulRunTimeCounter; - } - + ulRunTimeCounter = ulTaskGetIdleRunTimeCounter(); ulReturn = ulRunTimeCounter / ulTotalTime; } else From 15ec8b8995d90c07605bd25a017ff1669f288bca Mon Sep 17 00:00:00 2001 From: John Boiles Date: Wed, 12 Feb 2025 21:14:22 -0800 Subject: [PATCH 3/3] POSIX Simulator: Assert if vPortYield called from a non-FreeRTOS thread (#1247) --- portable/ThirdParty/GCC/Posix/port.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/portable/ThirdParty/GCC/Posix/port.c b/portable/ThirdParty/GCC/Posix/port.c index ff386ac9f..1153e7f67 100644 --- a/portable/ThirdParty/GCC/Posix/port.c +++ b/portable/ThirdParty/GCC/Posix/port.c @@ -384,6 +384,10 @@ static void prvPortYieldFromISR( void ) void vPortYield( void ) { + /* This must never be called from outside of a FreeRTOS-owned thread, or + * the thread could get stuck in a suspended state. */ + configASSERT( prvIsFreeRTOSThread() == pdTRUE ); + vPortEnterCritical(); prvPortYieldFromISR();