Skip to content

Commit b118a8b

Browse files
feat(freertos-smp): Added xTaskRemoveFromEventListFromISR()
1 parent 11a37a5 commit b118a8b

File tree

4 files changed

+109
-14
lines changed

4 files changed

+109
-14
lines changed

include/FreeRTOS.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,10 +2146,18 @@
21462146
#define traceENTER_xTaskRemoveFromEventList( pxEventList )
21472147
#endif
21482148

2149+
#ifndef traceENTER_xTaskRemoveFromEventListFromISR
2150+
#define traceENTER_xTaskRemoveFromEventListFromISR( pxEventList )
2151+
#endif
2152+
21492153
#ifndef traceRETURN_xTaskRemoveFromEventList
21502154
#define traceRETURN_xTaskRemoveFromEventList( xReturn )
21512155
#endif
21522156

2157+
#ifndef traceRETURN_xTaskRemoveFromEventListFromISR
2158+
#define traceRETURN_xTaskRemoveFromEventListFromISR( xReturn )
2159+
#endif
2160+
21532161
#ifndef traceENTER_vTaskRemoveFromUnorderedEventList
21542162
#define traceENTER_vTaskRemoveFromUnorderedEventList( pxEventListItem, xItemValue )
21552163
#endif

include/task.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3720,6 +3720,8 @@ void vTaskPlaceOnEventListRestricted( List_t * const pxEventList,
37203720
* Removes a task from both the specified event list and the list of blocked
37213721
* tasks, and places it on a ready queue.
37223722
*
3723+
* Do not call this function from an ISR context. Call xTaskRemoveFromEventListFromISR() instead.
3724+
*
37233725
* xTaskRemoveFromEventList()/vTaskRemoveFromUnorderedEventList() will be called
37243726
* if either an event occurs to unblock a task, or the block timeout period
37253727
* expires.
@@ -3736,6 +3738,23 @@ void vTaskPlaceOnEventListRestricted( List_t * const pxEventList,
37363738
* making the call, otherwise pdFALSE.
37373739
*/
37383740
BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) PRIVILEGED_FUNCTION;
3741+
3742+
/*
3743+
* THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY
3744+
* INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS
3745+
* AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
3746+
*
3747+
* THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED.
3748+
*
3749+
* Removes a task from both the specified event list and the list of blocked
3750+
* tasks, and places it on a ready queue. This function is the ISR-safe version
3751+
* of xTaskRemoveFromEventList().
3752+
*
3753+
* @return pdTRUE if the task being removed has a higher priority than the task
3754+
* making the call, otherwise pdFALSE.
3755+
*/
3756+
BaseType_t xTaskRemoveFromEventListFromISR( const List_t * const pxEventList ) PRIVILEGED_FUNCTION;
3757+
37393758
void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem,
37403759
const TickType_t xItemValue ) PRIVILEGED_FUNCTION;
37413760

queue.c

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,20 @@ static void prvCopyDataFromQueue( Queue_t * const pxQueue,
222222
* the queue set that the queue contains data.
223223
*/
224224
static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue ) PRIVILEGED_FUNCTION;
225-
#endif
225+
226+
/*
227+
* A version of prvNotifyQueueSetContainer() that can be called from an
228+
* interrupt service routine (ISR).
229+
*/
230+
static BaseType_t prvNotifyQueueSetContainerFromISR( const Queue_t * const pxQueue ) PRIVILEGED_FUNCTION;
231+
232+
/*
233+
* This function serves as a generic implementation for prvNotifyQueueSetContainer()
234+
* and prvNotifyQueueSetContainerFromISR().
235+
*/
236+
static BaseType_t prvNotifyQueueSetContainerGeneric( const Queue_t * const pxQueue,
237+
const BaseType_t xIsISR ) PRIVILEGED_FUNCTION;
238+
#endif /* if ( configUSE_QUEUE_SETS == 1 ) */
226239

227240
/*
228241
* Called after a Queue_t structure has been allocated either statically or
@@ -1294,7 +1307,7 @@ BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue,
12941307
* in the queue has not changed. */
12951308
mtCOVERAGE_TEST_MARKER();
12961309
}
1297-
else if( prvNotifyQueueSetContainer( pxQueue ) != pdFALSE )
1310+
else if( prvNotifyQueueSetContainerFromISR( pxQueue ) != pdFALSE )
12981311
{
12991312
/* The queue is a member of a queue set, and posting
13001313
* to the queue set caused a higher priority task to
@@ -1317,7 +1330,7 @@ BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue,
13171330
{
13181331
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
13191332
{
1320-
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
1333+
if( xTaskRemoveFromEventListFromISR( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
13211334
{
13221335
/* The task waiting has a higher priority so
13231336
* record that a context switch is required. */
@@ -1345,7 +1358,7 @@ BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue,
13451358
{
13461359
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
13471360
{
1348-
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
1361+
if( xTaskRemoveFromEventListFromISR( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
13491362
{
13501363
/* The task waiting has a higher priority so record that a
13511364
* context switch is required. */
@@ -1468,7 +1481,7 @@ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue,
14681481
{
14691482
if( pxQueue->pxQueueSetContainer != NULL )
14701483
{
1471-
if( prvNotifyQueueSetContainer( pxQueue ) != pdFALSE )
1484+
if( prvNotifyQueueSetContainerFromISR( pxQueue ) != pdFALSE )
14721485
{
14731486
/* The semaphore is a member of a queue set, and
14741487
* posting to the queue set caused a higher priority
@@ -1491,7 +1504,7 @@ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue,
14911504
{
14921505
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
14931506
{
1494-
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
1507+
if( xTaskRemoveFromEventListFromISR( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
14951508
{
14961509
/* The task waiting has a higher priority so
14971510
* record that a context switch is required. */
@@ -1519,7 +1532,7 @@ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue,
15191532
{
15201533
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
15211534
{
1522-
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
1535+
if( xTaskRemoveFromEventListFromISR( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
15231536
{
15241537
/* The task waiting has a higher priority so record that a
15251538
* context switch is required. */
@@ -2111,7 +2124,7 @@ BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue,
21112124
{
21122125
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
21132126
{
2114-
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
2127+
if( xTaskRemoveFromEventListFromISR( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
21152128
{
21162129
/* The task waiting has a higher priority than us so
21172130
* force a context switch. */
@@ -3354,6 +3367,19 @@ BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue )
33543367
#if ( configUSE_QUEUE_SETS == 1 )
33553368

33563369
static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue )
3370+
{
3371+
/* Call the generic version with xIsISR = pdFALSE to indicate task context */
3372+
return prvNotifyQueueSetContainerGeneric( pxQueue, pdFALSE );
3373+
}
3374+
3375+
static BaseType_t prvNotifyQueueSetContainerFromISR( const Queue_t * const pxQueue )
3376+
{
3377+
/* Call the generic version with xIsISR = pdTRUE to indicate ISR context */
3378+
return prvNotifyQueueSetContainerGeneric( pxQueue, pdTRUE );
3379+
}
3380+
3381+
static BaseType_t prvNotifyQueueSetContainerGeneric( const Queue_t * const pxQueue,
3382+
const BaseType_t xIsISR )
33573383
{
33583384
Queue_t * pxQueueSetContainer = pxQueue->pxQueueSetContainer;
33593385
BaseType_t xReturn = pdFALSE;
@@ -3379,7 +3405,18 @@ BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue )
33793405
{
33803406
if( listLIST_IS_EMPTY( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) == pdFALSE )
33813407
{
3382-
if( xTaskRemoveFromEventList( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) != pdFALSE )
3408+
BaseType_t xHigherPriorityTaskWoken;
3409+
3410+
if( xIsISR == pdTRUE )
3411+
{
3412+
xHigherPriorityTaskWoken = xTaskRemoveFromEventListFromISR( &( pxQueueSetContainer->xTasksWaitingToReceive ) );
3413+
}
3414+
else
3415+
{
3416+
xHigherPriorityTaskWoken = xTaskRemoveFromEventList( &( pxQueueSetContainer->xTasksWaitingToReceive ) );
3417+
}
3418+
3419+
if( xHigherPriorityTaskWoken != pdFALSE )
33833420
{
33843421
/* The task waiting has a higher priority. */
33853422
xReturn = pdTRUE;

tasks.c

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,13 @@ static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters ) PRIVILEGED_FUNCTION;
704704
*/
705705
static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION;
706706

707+
/*
708+
* Private helper function to remove a task from an event list. This function
709+
* is shared between the task context and ISR context versions.
710+
*/
711+
static BaseType_t prvTaskRemoveFromEventList( const List_t * const pxEventList,
712+
const BaseType_t xIsISR ) PRIVILEGED_FUNCTION;
713+
707714
/*
708715
* The currently executing task is entering the Blocked state. Add the task to
709716
* either the current or the overflow delayed task list.
@@ -5748,6 +5755,33 @@ void vTaskPlaceOnUnorderedEventList( List_t * pxEventList,
57485755
/*-----------------------------------------------------------*/
57495756

57505757
BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList )
5758+
{
5759+
traceENTER_xTaskRemoveFromEventList( pxEventList );
5760+
5761+
/* Call the private helper function with xIsISR = pdFALSE to indicate task context */
5762+
BaseType_t xReturn = prvTaskRemoveFromEventList( pxEventList, pdFALSE );
5763+
5764+
traceRETURN_xTaskRemoveFromEventList( xReturn );
5765+
return xReturn;
5766+
}
5767+
5768+
/*-----------------------------------------------------------*/
5769+
5770+
BaseType_t xTaskRemoveFromEventListFromISR( const List_t * const pxEventList )
5771+
{
5772+
traceENTER_xTaskRemoveFromEventListFromISR( pxEventList );
5773+
5774+
/* Call the private helper function with xIsISR = pdTRUE to indicate ISR context */
5775+
BaseType_t xReturn = prvTaskRemoveFromEventList( pxEventList, pdTRUE );
5776+
5777+
traceRETURN_xTaskRemoveFromEventListFromISR( xReturn );
5778+
return xReturn;
5779+
}
5780+
5781+
/*-----------------------------------------------------------*/
5782+
5783+
static BaseType_t prvTaskRemoveFromEventList( const List_t * const pxEventList,
5784+
const BaseType_t xIsISR )
57515785
{
57525786
TCB_t * pxUnblockedTCB;
57535787
BaseType_t xReturn;
@@ -5756,15 +5790,13 @@ BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList )
57565790
UBaseType_t uxSavedInterruptStatus;
57575791
#endif /* #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) */
57585792

5759-
traceENTER_xTaskRemoveFromEventList( pxEventList );
5760-
57615793
#if ( !( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) )
57625794

57635795
/* THIS FUNCTION MUST BE CALLED FROM A CRITICAL SECTION. It can also be
57645796
* called from a critical section within an ISR. */
57655797
#else /* #if ( ! ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) ) */
57665798
/* Lock the kernel data group as we are about to access its members */
5767-
if( portCHECK_IF_IN_ISR() == pdTRUE )
5799+
if( xIsISR == pdTRUE )
57685800
{
57695801
uxSavedInterruptStatus = kernelENTER_CRITICAL_FROM_ISR();
57705802
}
@@ -5869,7 +5901,7 @@ else
58695901
}
58705902

58715903
/* We are done accessing the kernel data group. Unlock it. */
5872-
if( portCHECK_IF_IN_ISR() == pdTRUE )
5904+
if( xIsISR == pdTRUE )
58735905
{
58745906
kernelEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus );
58755907
}
@@ -5879,7 +5911,6 @@ else
58795911
}
58805912
#endif /* #if ( ( portUSING_GRANULAR_LOCKS == 1 ) && ( configNUMBER_OF_CORES > 1 ) ) */
58815913

5882-
traceRETURN_xTaskRemoveFromEventList( xReturn );
58835914
return xReturn;
58845915
}
58855916
/*-----------------------------------------------------------*/

0 commit comments

Comments
 (0)