Why systick decreases real time responsiveness by masking interrupts for all the service routine ?

pstepien wrote on Tuesday, February 09, 2016:

Systick interrupt should be at lowest possible level but indeed through its implementation it is at the highest system level by using portSET_INTERRUPT_MASK_FROM_ISR/portCLEAR_INTERRUPT_MASK_FROM_ISR at entry/exit and thus masking interrupts using rtos api for all the systick isr routine execution where only during tasks list manipulation it should mask/unmask interrupts

(FreeRTOS V8.2.3) Source\portable\GCC\ARM_CM4F\port.c:

void xPortSysTickHandler( void )
{
	/* The SysTick runs at the lowest interrupt priority, so when this interrupt
	executes all interrupts must be unmasked.  There is therefore no need to
	save and then restore the interrupt mask value as its value is already
	known. */
	( void ) portSET_INTERRUPT_MASK_FROM_ISR();
	{
		/* Increment the RTOS tick. */
		if( xTaskIncrementTick() != pdFALSE )
		{
			/* A context switch is required.  Context switching is performed in
			the PendSV interrupt.  Pend the PendSV interrupt. */
			portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
		}
	}
	portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
}

When taking a look into xTaskIncrementTick we see that there is code that does delayed tasks list manipulation, removing woken tasks from blocked state list and event waiting lists, adding to ready list
1. delayed tasks list manipulation may be executed only from thread so does not need to be inside citical section (under masked interrupts) (bad idea, maybe done in isr)
2. only removing woken tasks from blocked state list and event waiting lists and adding to ready list should be inside critical section (under masked interrupts)

(FreeRTOS V8.2.3) tasks.c:

				for( ;; )
				{
<---- begin critical section here
                    if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE )
					{
						/* The delayed list is empty.  Set xNextTaskUnblockTime
						to the maximum possible value so it is extremely
						unlikely that the
						if( xTickCount >= xNextTaskUnblockTime ) test will pass
						next time through. */
						xNextTaskUnblockTime = portMAX_DELAY;
<---- end critical section here
						break;
					}
					else
					{
						/* The delayed list is not empty, get the value of the
						item at the head of the delayed list.  This is the time
						at which the task at the head of the delayed list must
						be removed from the Blocked state. */
						pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList );
						xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xGenericListItem ) );

						if( xConstTickCount < xItemValue )
						{
							/* It is not time to unblock this item yet, but the
							item value is the time at which the task at the head
							of the blocked list must be removed from the Blocked
							state -	so record the item value in
							xNextTaskUnblockTime. */
							xNextTaskUnblockTime = xItemValue;
							break;
						}
						else
						{
							mtCOVERAGE_TEST_MARKER();
						}

						/* It is time to remove the item from the Blocked state. */
						( void ) uxListRemove( &( pxTCB->xGenericListItem ) );

						/* Is the task waiting on an event also?  If so remove
						it from the event list. */
						if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
						{
							( void ) uxListRemove( &( pxTCB->xEventListItem ) );
						}
						else
						{
							mtCOVERAGE_TEST_MARKER();
						}

						/* Place the unblocked task into the appropriate ready
						list. */
						prvAddTaskToReadyList( pxTCB );
<---- end critical section here

Please let me know if I am right.

If yes shouldn’t it be considered in next versions of RTOS improve the real time responsiveness ?

Best regards,
Piotr

davedoors wrote on Tuesday, February 09, 2016:

Are you suggesting the critical section could only be around “removing woken tasks from blocked state list and event waiting lists and adding to ready list should be inside critical section” and not also around “delayed tasks list manipulation” to make it shorter? Did you consider also that other interrupts can move a task out of a delayed task list? For example if a semaphore is used in an interrupt it can move a task from a delayed list to an ready list.

pstepien wrote on Tuesday, February 09, 2016:

Dave,
You are right, removing from delayed tasks list can be done in isr and must be under critical section.

My point is rather if it is necessary to mask interrupts for whole systick isr. Critical section should be as small as possible. My idea is to divide big block of critical section in systick into smaller parts allowing better response to higher priority interrupt.
I have updated the code above with suggested placement of critical section

Regards,
Piotr