Is this safe to walk through a RTOS list using listGET_OWNER_OF_NEXT_ENTRY?

FreeRTOS Kernel V10.4.3

According to RTOS documentation, listGET_OWNER_OF_NEXT_ENTRY is used to walk through a list. Using multiple calls to this macro it is therefore possible to move through every item contained in a list. This macro first increments pxIndex to the next item in the list and then returns that entry’s pxOwner parameter.

Therefore, I took into advantage macro’s list walk through ability in order to read data from every item contained in tasks and timers lists. This new list walking through code is used by two different applications.

List walk through pseudo code:

	void list_walking_through( List_t * pxList ) 
	{
		TCB_t * pxFirstTCB, * pxNextTCB;

		if( listLIST_IS_EMPTY( pxList ) == pdFALSE  )
		{
			pxFirstTCB = ( TCB_t * )listGET_OWNER_OF_HEAD_ENTRY( pxList );
			pxNextTCB = pxFirstTCB;
			
			do
			{
				/************
				 * do stuff *
				 ************/
				 
				listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList );
			}while( pxNextTCB != pxFirstTCB );
		}
		
		return;
	}

I have observed an odd scenario after each operation - pxIndex doesn’t point to the same item as before. Example:

  1. Assume pxIndex points to item C at the beginning.
    . . . . . . idx
    [ A , B , C , D, MARKER ]
  2. pxOwner parameter from item D sets as while loop stop condition and increment pxIndex.
    . . . . . . . . . idx
    [ A , B , C , D, MARKER ]
  3. After code execution, pxIndex points to item D.

Questions:
What could be the impact of pxIndex manipulation? I saw in the code that vListInsertEnd uses pxIndex for item insertion at the end of a cyclic list.
Is it safe to use listGET_OWNER_OF_HEAD_ENTRY by an application?
What is the appropriate way to scan the list?

scan the list under control of the critical section. Your task may get interrupted during the traversal which may leave it incoherent.

Hi @RAc
Sorry for not mentioning it before but assume that the operation is protected under a critical section by the caller.

edited: As long as the critical section is working properly, the system task lists should be coherent. Do you have code to share?

The operation does use the stateful structure List_t to maintain list position. As RAc has stated, for this reason it need be protected, for example by a critical section, to avoid multiple accessors modifying state.

You can alternatively use the listGET_NEXT() function which does not update the state of List_t. However this could still be effected by other operations which update the list and so protection from other list modification operations is still required.

Let me know if this answers your questions.

So as far as I understood, even though the operation is protected, it’s not recommended to use this macro by ordinary application since the OS relies on list state.
Could you please confirm? I suggest updating RTOS documentation. Incorrect list macros usage by the developer can eventually influence the OS.

For example, ready task list state may changes (pxReadyTasksLists[#n]) after walk through via the introduced API in post description, and FIFO pattern breaks accordingly because pxIndex does not point to the latest inserted element - list tail.

Read every item contained in a list from head to tail using listGET_HEAD_ENTRY() and listGET_NEXT() macros seem safer, they don’t update/change list state.

Many thanks!

Confirming, listGET_HEAD_ENTRY() and listGET_NEXT() should be used instead due to the side effects introduced by modifying pxIndex. Only use the listGET_OWNER_OF_NEXT_ENTRY macro when intending to update pxIndex.