我在学习ucos-ii代码的时候发现OS_FlagUnlink()代码有一段可以简化。
但是作者没有简化,网上也没找到有人讨论这段代码,有点奇怪。怀疑是不是我想的简化有问题,发出来希望有人讨论下。
原OS_FlagUnlink()函数(os_flag.c)
void OS_FlagUnlink (OS_FLAG_NODE *pnode)
{
#if OS_TASK_DEL_EN > 0
OS_TCB *ptcb;
#endif
OS_FLAG_GRP *pgrp;
OS_FLAG_NODE *pnode_prev;
OS_FLAG_NODE *pnode_next;
pnode_prev = (OS_FLAG_NODE *)pnode->OSFlagNodePrev;
pnode_next = (OS_FLAG_NODE *)pnode->OSFlagNodeNext;
if (pnode_prev == (OS_FLAG_NODE *)0) { /* Is it first node in wait list? */
pgrp = (OS_FLAG_GRP *)pnode->OSFlagNodeFlagGrp;
/* Update list for new 1st node */
pgrp->OSFlagWaitList = (void *)pnode_next;
if (pnode_next != (OS_FLAG_NODE *)0) {
/* Link new 1st node PREV to NULL */
pnode_next->OSFlagNodePrev = (OS_FLAG_NODE *)0;
}
} else { /* No, A node somewhere in the list */
/* Link around the node to unlink */
pnode_prev->OSFlagNodeNext = pnode_next;
/* Was this the LAST node? */
if (pnode_next != (OS_FLAG_NODE *)0) {
/* No, Link around current node */
pnode_next->OSFlagNodePrev = pnode_prev;
}
}
#if OS_TASK_DEL_EN > 0
ptcb = (OS_TCB *)pnode->OSFlagNodeTCB;
ptcb->OSTCBFlagNode = (OS_FLAG_NODE *)0;
#endif
}
被我简化后的函数代码
void OS_FlagUnlink (OS_FLAG_NODE *pnode)
{
#if OS_TASK_DEL_EN > 0
OS_TCB *ptcb;
#endif
OS_FLAG_GRP *pgrp;
OS_FLAG_NODE *pnode_prev;
OS_FLAG_NODE *pnode_next;
pnode_prev = (OS_FLAG_NODE *)pnode->OSFlagNodePrev;
pnode_next = (OS_FLAG_NODE *)pnode->OSFlagNodeNext;
if (pnode_prev == (OS_FLAG_NODE *)0) { /* Is it first node in wait list? */
pgrp = (OS_FLAG_GRP *)pnode->OSFlagNodeFlagGrp;
/* Update list for new 1st node */
pgrp->OSFlagWaitList = (void *)pnode_next;
} else { /* No, A node somewhere in the list */
/* Link around the node to unlink */
pnode_prev->OSFlagNodeNext = pnode_next;
}
if (pnode_next != (OS_FLAG_NODE *)0) { /* Was this the LAST node? */
/* No, Link around current node */
pnode_next->OSFlagNodePrev = pnode_prev;
}
#if OS_TASK_DEL_EN > 0
ptcb = (OS_TCB *)pnode->OSFlagNodeTCB;
ptcb->OSTCBFlagNode = (OS_FLAG_NODE *)0;
#endif
}
主要是把下面的代码从if和else里提取出来。
if (pnode_next != (OS_FLAG_NODE *)0) { /* Was this the LAST node? */
/* No, Link around current node */
pnode_next->OSFlagNodePrev = pnode_prev;
}
因为
if (pnode_prev == (OS_FLAG_NODE *)0) { /* Is it first node in wait list? */
/* Link new 1st node PREV to NULL */
pnode_next->OSFlagNodePrev = (OS_FLAG_NODE *)0;
和
/* No, Link around current node */
pnode_next->OSFlagNodePrev = pnode_prev;
效果是一样的。
uCOS-II-V290版本的代码就是原OS_FlagUnlink()代码一样的。