From b26bb0d715bc05bd04f778f04352404eaab95270 Mon Sep 17 00:00:00 2001 From: wangfei_chen Date: Fri, 21 Feb 2025 15:17:45 +0800 Subject: [PATCH 1/2] timer: prevent infinate loop on one-shot timer start One-shot timers that expire after a single tick could immediately transition to a dormant state, despite xTimerCommandSent being pdTRUE. This situation resulted in a potential deadlock due to an infinite loop in the timer activation process. Signed-off-by: wangfei_chen --- FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_timer.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_timer.c b/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_timer.c index 4eca283..e9e7c42 100755 --- a/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_timer.c +++ b/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_timer.c @@ -54,6 +54,7 @@ typedef struct timer_internal StaticTimer_t xTimerBuffer; /**< Memory that holds the FreeRTOS timer. */ struct sigevent xTimerEvent; /**< What to do when this timer expires. */ TickType_t xTimerPeriod; /**< Period of this timer. */ + UBaseType_t uxTimerCallbacked; /**< Number of Timer Callback times. */ } timer_internal_t; /*-----------------------------------------------------------*/ @@ -94,6 +95,7 @@ void prvTimerCallback( TimerHandle_t xTimer ) pxTimer->xTimerEvent.sigev_value.sival_ptr ); } } + pxTimer->uxTimerCallbacked++; } /*-----------------------------------------------------------*/ @@ -273,6 +275,9 @@ int timer_settime( timer_t timerid, } } + /* Set uxTimerCallbacked before timer start. */ + pxTimer->uxTimerCallbacked = 0 + /* If xNextTimerExpiration is still 0, that means that it_value specified * an absolute timeout in the past. Per POSIX spec, a notification should be * triggered immediately. */ @@ -286,7 +291,8 @@ int timer_settime( timer_t timerid, xTimerCommandSent = xTimerChangePeriod( xTimer, xNextTimerExpiration, xNextTimerExpiration ); /* Wait until the timer start command is processed. */ - while( ( xTimerCommandSent != pdFAIL ) && ( xTimerIsTimerActive( xTimer ) == pdFALSE ) ) + while( ( xTimerCommandSent != pdFAIL ) && ( xTimerIsTimerActive( xTimer ) == pdFALSE ) && \ + ( pxTimer->uxTimerCallbacked == 0 ) ) { vTaskDelay( 1 ); } From e5af1d22827bf3dc38f2d70f0dbc45aeaabf5846 Mon Sep 17 00:00:00 2001 From: Gaurav Aggarwal Date: Mon, 24 Feb 2025 16:19:40 +0000 Subject: [PATCH 2/2] Code review suggestions Signed-off-by: Gaurav Aggarwal --- FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_timer.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_timer.c b/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_timer.c index e9e7c42..9237de7 100755 --- a/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_timer.c +++ b/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_timer.c @@ -54,7 +54,7 @@ typedef struct timer_internal StaticTimer_t xTimerBuffer; /**< Memory that holds the FreeRTOS timer. */ struct sigevent xTimerEvent; /**< What to do when this timer expires. */ TickType_t xTimerPeriod; /**< Period of this timer. */ - UBaseType_t uxTimerCallbacked; /**< Number of Timer Callback times. */ + UBaseType_t uxTimerCallbackInvocations; /**< Number of times the timer callback has been invoked. */ } timer_internal_t; /*-----------------------------------------------------------*/ @@ -95,7 +95,7 @@ void prvTimerCallback( TimerHandle_t xTimer ) pxTimer->xTimerEvent.sigev_value.sival_ptr ); } } - pxTimer->uxTimerCallbacked++; + pxTimer->uxTimerCallbackInvocations++; } /*-----------------------------------------------------------*/ @@ -275,8 +275,8 @@ int timer_settime( timer_t timerid, } } - /* Set uxTimerCallbacked before timer start. */ - pxTimer->uxTimerCallbacked = 0 + /* Set uxTimerCallbackInvocations before timer start. */ + pxTimer->uxTimerCallbackInvocations = 0 /* If xNextTimerExpiration is still 0, that means that it_value specified * an absolute timeout in the past. Per POSIX spec, a notification should be @@ -291,8 +291,9 @@ int timer_settime( timer_t timerid, xTimerCommandSent = xTimerChangePeriod( xTimer, xNextTimerExpiration, xNextTimerExpiration ); /* Wait until the timer start command is processed. */ - while( ( xTimerCommandSent != pdFAIL ) && ( xTimerIsTimerActive( xTimer ) == pdFALSE ) && \ - ( pxTimer->uxTimerCallbacked == 0 ) ) + while( ( xTimerCommandSent != pdFAIL ) && + ( xTimerIsTimerActive( xTimer ) == pdFALSE ) && + ( pxTimer->uxTimerCallbackInvocations == 0 ) ) { vTaskDelay( 1 ); }