SylixOS唤醒链简介
对于任何系统timer中断就像系统的心跳,不断地更新着系统的时间,同时也不断地更新着基于RR调度策略的时间片,以及持续的计算睡眠线程的睡眠时间等等。SylixOS唤醒链将SylixOS中所有需要睡眠等待的线程进行了一个统一管理,使得在使用上更加方便。SylixOS唤醒链基于差分链的原理,使得在效率上更加高效。
SylixOS唤醒链原理
相关结构
SylixOS唤醒链由下面两个结构体管理:
typedef struct {
LW_LIST_LINE WUN_lineManage; /* 扫描链表 */
BOOL WUN_bInQ; /* 是否在扫描链中 */
ULONG WUN_ulCounter; /* 相对等待时间 */
} LW_CLASS_WAKEUP_NODE;
typedef struct {
LW_LIST_LINE_HEADER WU_plineHeader;
PLW_LIST_LINE WU_plineOp;
} LW_CLASS_WAKEUP;
LW_CLASS_WAKEUP_NODE结构体定义了一个唤醒节点:
- WUN_lineManage指向下一个节点;
- WUN_bInQ标示是否在链中;
- WUN_ulCounter等待时间计数。
LW_CLASS_WAKEUP结构体定义了唤醒链的类型如:_K_wuDelay、_K_wuWatchDog等
- WU_plineHeader是唤醒链节点头;
- WU_plineOp指向下一个要操作的节点。
对唤醒链的操作SylixOS使用差分时间链,基本原理如下:
假设现在有3个节点A、B、C,A节点需要3个时间点就应被激活,B节点需要6个时间点应被激活,C节点需要10个时间点应被激活,那么它们在链上的顺序应该如下图所示:
这种结构保证了不用每次遍历链表去找相应的节点进行减操作,只需减最左边的节点,当节点计数减到1时,表示时间到,删除该节点即可。
添加一个新的节点,需要对链表进行一次遍历,例如:插入节点D是9个时间点,首先判断第一个节点3小于9,这时我们需要9-3然后向后继续找,第2个节点3小于6说明还要向后继续找,依次类推找到C节点处因此此时6-3=3 < 4因此应该插到B和C之间。
相关函数
VOID _WakeupAdd(PLW_CLASS_WAKEUP pwu, PLW_CLASS_WAKEUP_NODE pwun);
此函数向指定的唤醒链中增加一个节点
VOID _WakeupDel(PLW_CLASS_WAKEUP pwu, PLW_CLASS_WAKEUP_NODE pwun);
此函数将指定的节点从链上删除。
VOID _WakeupStatus (PLW_CLASS_WAKEUP pwu, PLW_CLASS_WAKEUP_NODE pwun, ULONG *pulLeft);
此函数获得指定节点的状态。