本帖最后由 caijie001 于 2018-6-12 13:12 编辑
列表项的插入 源码: void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )
{
ListItem_t *pxIterator;
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
listTEST_LIST_INTEGRITY( pxList );
listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
if( xValueOfInsertion == portMAX_DELAY )
{
pxIterator = pxList->xListEnd.pxPrevious;
}
else
{
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
{
/* There is nothing to do here, just iterating to the wanted
insertion position. */
}
}
pxNewListItem->pxNext = pxIterator->pxNext;
pxNewListItem->pxNext->pxPrevious = pxNewListItem;
pxNewListItem->pxPrevious = pxIterator;
pxIterator->pxNext = pxNewListItem;
/* Remember which list the item is in. This allows fast removal of the
item later. */
pxNewListItem->pvContainer = ( void * ) pxList;
( pxList->uxNumberOfItems )++;
}
传入的参数: pxList:列表项要插入的列表。 pxNewListItem:要插入的列表项是什么。
pxList决定了插入哪个列表,pxNewListItem中的xItemValue值决定了列表项插入列表的位置。 ListItem_t *pxIterator;
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
定义一个辅助的列表项pxIterator,用来迭代找出插入新列表项的位置,并且保存获取要插入的列表项pxNewListItem的xItemValue。 如果打开了列表项完整性检查,就要用户实现configASSERT(),源码中有说明。 既然是要插入列表项,那么肯定是要知道列表项的位置了,如果新插入列表项的xItemValue是最大的话(portMAX_DELAY),就直接插入列表项的末尾。否则就需要比较列表中各个列表项的xItemValue的大小来进行排列。然后得出新列表项插入的位置。 for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )
上面源码就是实现比较的过程。 与上面的从列表项末尾插入的源码一样,FreeRTOS的代码通用性很强,逻辑思维也很强。
如果列表中列表项的数量为0,那么插入的列表项就是在初始化列表项的后面。如下图所示:
过程分析: 新列表项的pxNext指向pxIterator->pxNext,也就是指向了xListEnd(pxIterator)。 pxNewListItem->pxNext = pxIterator->pxNext;
而xListEnd(pxIterator)的pxPrevious指向则为pxNewListItem。 pxNewListItem->pxNext->pxPrevious = pxNewListItem;
新列表项的(pxPrevious)指针指向xListEnd(pxIterator) pxIterator 的 pxNext 指向了新列表项 pxNewListItem->pxPrevious = pxIterator;
pxIterator->pxNext = pxNewListItem;
与从末尾插入列表项其实是一样的,前提是当前列表中列表项的数目为0。 |