FreeRTOS 的链表 vListInsertEnd() 方法笔记

in #cn-programming7 years ago (edited)

在研究 FreeRTOS 内核时, 发现自已一直理解错了 vListInsertEnd() 的意思, 特此记录下.

vListInsertEnd() 这个方法比较迷惑人, 这个方法真正的意思是尾插, 而不是插到链表的尾部. 这两者的意思是不一样的.

那究竟什么是尾插呢? 我们应该知道头插, 给定一个链表节点 A, 头插就是说新的节点要插在 A 的后面, 而尾插则是说新的节点要插在 A 的前面. 这就是尾插的意思: 把给定的节点当作尾部.

FreeRTOS 的链表结构 List_t 中有一个成员叫做 pxIndex, 这个成员是用来遍历这个链表用的, 具体来说就是在同优先级任务链上, 依次取得下一次任务以达到同优先级任务共享 CPU 时间的. List_t 结构中还有一个成员叫做 xListEnd, xListEnd 是不包含有效数据的节点, 它标识着这个链表的真正的尾部.

之前令我误解的一点就是, 我总以为 vListInsertEnd() 就是将新的节点插到整个链表的尾部, 也就是 xListEnd 的前面. 但是 vListInsertEnd() 却是将新的节点插入到 pxIndex 前面. 我想了好久没明白这什么意思, 直到我看到 listGET_OWNER_OF_NEXT_ENTRY(pxTCB, pxList) 这个宏我才明白, 这个宏就是每次调度器选择下一个任务时所调用的, 这个宏会每次将 pxIndex 更新为它后面的节点. 所以, 为什么 vListInsertEnd() 是将新的节点插入到 pxIndex 前面也就解释的通了, 这是为了更公平的让各个任务共享时间片. 比如说当前有如下的任务链表, 每个任务的优先级相同:

1    2    3    4    5    end

其中 1, 2, 3 任务刚刚依次获得完时间片, pxIndex 现在指向 4, 那么现在又来了一个新的任务 6, 当调用 vListInsertEnd() 的时候, 任务 6 就会被插入到 4 前面, 之后调度就会变成 4, 5, 1, 2, 3, 6, … 而如果 6 被插入 end 前面, 那之后的调度就会变成 4, 5, 6, 1, 2, 3, … 显然这对 1, 2, 3 是不公平的.

FreeRTOS 确实是个精悍的内核, 用最少的代码实现了非常多的复杂精细, 逻辑缜密的功能, 值得一看!


其它文章

数字货币

数据分析

交易所

编程系列

Coin Marketplace

STEEM 0.18
TRX 0.13
JST 0.029
BTC 58625.96
ETH 3101.66
USDT 1.00
SBD 2.41