Skip to content

Commit a10f84e

Browse files
feat(freertos-smp): Create private function for task preemption enable
1 parent cc09d63 commit a10f84e

File tree

2 files changed

+52
-18
lines changed

2 files changed

+52
-18
lines changed

include/task.h

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ typedef enum
361361
mtCOVERAGE_TEST_MARKER(); \
362362
} \
363363
/* Re-enable preemption */ \
364-
vTaskPreemptionEnable( NULL ); \
364+
prvTaskPreemptionEnable( NULL ); \
365365
} while( 0 )
366366
#endif /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */
367367

@@ -417,14 +417,12 @@ typedef enum
417417
* \ingroup GranularLocks
418418
*/
419419
#if ( portUSING_GRANULAR_LOCKS == 1 )
420-
#define taskDATA_GROUP_UNLOCK( pxTaskSpinlock ) \
421-
do { \
422-
{ \
423-
portRELEASE_SPINLOCK( portGET_CORE_ID(), ( portSPINLOCK_TYPE * ) ( pxTaskSpinlock ) ); \
424-
} \
425-
/* Re-enable preemption after releasing the task spinlock. */ \
426-
vTaskPreemptionEnable( NULL ); \
427-
} while( 0 )
420+
#define taskDATA_GROUP_UNLOCK( pxTaskSpinlock ) \
421+
( { \
422+
portRELEASE_SPINLOCK( portGET_CORE_ID(), ( portSPINLOCK_TYPE * ) ( pxTaskSpinlock ) ); \
423+
/* Re-enable preemption after releasing the task spinlock. */ \
424+
prvTaskPreemptionEnable( NULL ); \
425+
} )
428426
#endif /* #if ( portUSING_GRANULAR_LOCKS == 1 ) */
429427

430428
/*-----------------------------------------------------------
@@ -1627,6 +1625,23 @@ BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION;
16271625
void vTaskPreemptionEnable( const TaskHandle_t xTask );
16281626
#endif
16291627

1628+
#if ( configUSE_TASK_PREEMPTION_DISABLE == 1 )
1629+
1630+
/*
1631+
* THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY
1632+
* INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS
1633+
* AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER.
1634+
*
1635+
* @param xTask The handle of the task to enable preemption. Passing NULL
1636+
* enables preemption for the calling task.
1637+
*
1638+
* @return pdTRUE if enabling preemption for the task resulted in a context
1639+
* switch, otherwise pdFALSE. This is used by the scheduler to determine if a
1640+
* context switch may be required following the enable.
1641+
*/
1642+
BaseType_t prvTaskPreemptionEnable( const TaskHandle_t xTask );
1643+
#endif
1644+
16301645
/*-----------------------------------------------------------
16311646
* SCHEDULER CONTROL
16321647
*----------------------------------------------------------*/

tasks.c

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,13 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
857857
TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION;
858858
#endif /* #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) */
859859

860+
/*
861+
* Helper function to enable preemption for a task.
862+
*/
863+
#if ( configUSE_TASK_PREEMPTION_DISABLE == 1 )
864+
BaseType_t prvTaskPreemptionEnable( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
865+
#endif /* #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) */
866+
860867
/*
861868
* freertos_tasks_c_additions_init() should only be called if the user definable
862869
* macro FREERTOS_TASKS_C_ADDITIONS_INIT() is defined, as that is the only macro
@@ -1096,7 +1103,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
10961103
xYieldPendings[ xCoreID ] = pdTRUE;
10971104
}
10981105
}
1099-
#else /* if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) */
1106+
#else /* if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) */
11001107
{
11011108
xLowestPriorityToPreempt = xCurrentCoreTaskPriority;
11021109
xLowestPriorityCore = xCoreID;
@@ -1413,7 +1420,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
14131420
xYieldPendings[ uxCore ] = pdTRUE;
14141421
}
14151422
}
1416-
#else /* if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) */
1423+
#else /* if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) */
14171424
{
14181425
xLowestPriority = xTaskPriority;
14191426
xLowestPriorityCore = ( BaseType_t ) uxCore;
@@ -3367,12 +3374,11 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
33673374

33683375
#if ( configUSE_TASK_PREEMPTION_DISABLE == 1 )
33693376

3370-
void vTaskPreemptionEnable( const TaskHandle_t xTask )
3377+
BaseType_t prvTaskPreemptionEnable( const TaskHandle_t xTask )
33713378
{
33723379
TCB_t * pxTCB;
33733380
UBaseType_t uxDeferredAction = 0U;
3374-
3375-
traceENTER_vTaskPreemptionEnable( xTask );
3381+
BaseType_t xAlreadyYielded = pdFALSE;
33763382

33773383
#if ( configLIGHTWEIGHT_CRITICAL_SECTION == 1 )
33783384
vKernelLightWeightEnterCritical();
@@ -3390,18 +3396,16 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
33903396

33913397
if( pxTCB->uxPreemptionDisable == 0U )
33923398
{
3393-
/* Process deferred state changes which were inflicted while
3394-
* preemption was disabled. */
33953399
if( pxTCB->uxDeferredStateChange != 0U )
33963400
{
3397-
/* Capture the deferred action to perform outside critical section */
33983401
uxDeferredAction = pxTCB->uxDeferredStateChange;
33993402
}
34003403
else
34013404
{
34023405
if( ( xYieldPendings[ pxTCB->xTaskRunState ] != pdFALSE ) && ( taskTASK_IS_RUNNING( pxTCB ) != pdFALSE ) )
34033406
{
34043407
prvYieldCore( pxTCB->xTaskRunState );
3408+
xAlreadyYielded = pdTRUE;
34053409
}
34063410
else
34073411
{
@@ -3425,7 +3429,6 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
34253429
kernelEXIT_CRITICAL();
34263430
#endif
34273431

3428-
/* Handle deferred actions outside critical section */
34293432
if( uxDeferredAction != 0U )
34303433
{
34313434
if( uxDeferredAction & tskDEFERRED_DELETION )
@@ -3440,8 +3443,24 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
34403443
{
34413444
mtCOVERAGE_TEST_MARKER();
34423445
}
3446+
3447+
/* Any deferred action on the task would result in a context switch. */
3448+
xAlreadyYielded = pdTRUE;
34433449
}
34443450

3451+
return xAlreadyYielded;
3452+
}
3453+
#endif /* #if ( configUSE_TASK_PREEMPTION_DISABLE == 1 ) */
3454+
/*-----------------------------------------------------------*/
3455+
3456+
#if ( configUSE_TASK_PREEMPTION_DISABLE == 1 )
3457+
3458+
void vTaskPreemptionEnable( const TaskHandle_t xTask )
3459+
{
3460+
traceENTER_vTaskPreemptionEnable( xTask );
3461+
3462+
( void ) prvTaskPreemptionEnable( xTask );
3463+
34453464
traceRETURN_vTaskPreemptionEnable();
34463465
}
34473466

0 commit comments

Comments
 (0)