单链表
单链表的结点链接是单方向的,在 SylixOS 中,单链表多用于操作系统资源分配,管理空闲资源,比如线程控制块的空闲控制块的管理,创建一个线程时就需要从空闲控制块链表中取出一个空闲控制块,删除线程时就需要将回收的控制块加入到空闲控制块链表中以备继续使用。
单向资源分配链表数据结构定义:
typedef struct __list_mono {
struct __list_mono *MONO_plistNext;
} LW_LIST_MONO;
- MONO_plistNext:资源表前向指针。
SylixOS 中,单链表主要有结点查找、分配、回收等链表操作。
指向下一个结点
#include <SylixOS.h>
VOID _list_mono_next (PLW_LIST_MONO *phead);
函数 _list_mono_next 原型分析:
- 参数 phead 是单链表结点指针的指针。
调用 _list_mono_next 函数可以让单链表指向下一个结点,如下图所示。
说明:
虚线表示函数执行前 phead 指针的指向,实线表示函数执行后 phead 指针的指向。
SylixOS 内核中线程可以安排它退出时需要调用的函数,这样的函数称为线程清理处理程序,一个线程可以建立多个清理处理程序,处理程序记录在栈中,其中将一个压栈函数运行并释放的接口 API_ThreadCleanupPop 函数就使用到 _list_mono_next 函数,通过 _list_mono_next 函数依次运行压入栈中的线程清理处理程序并释放。
获取下一个结点
#include <SylixOS.h>
PLW_LIST_MONO _list_mono_get_next (PLW_LIST_MONO pmono);
函数 _list_mono_get_next 原型分析:
- 此函数返回单链表下一个结点的指针。
- 参数 pmono 为单链表结点的指针。
调用 _list_mono_get_next 函数可以获取单链表下一个结点的指针,如下图所示。
SylixOS 内核中对具有依赖关系的模块管理和 C++全局对象析构函数列表的管理上使用到 _list_mono_get_next 函数。具有依赖关系的模块注册时,需要先注册底层模块,再注册上层模块;模块卸载时,就要反过来先卸载上层模块,再卸载底层模块,模块注册或卸载时的执行顺序就是由 _list_mono_get_next 函数来保证。
单链表分配
#include <SylixOS.h>
PLW_LIST_MONO _list_mono_allocate (PLW_LIST_MONO *phead);
PLW_LIST_MONO _list_mono_allocate_seq (PLW_LIST_MONO *phead,
PLW_LIST_MONO *ptail);
函数 _list_mono_allocate 原型分析:
- 此函数返回单链表下一个结点的指针。
- 参数 phead 是单链表头结点的指针。
函数 _list_mono_allocate_seq 原型分析:
- 此函数返回单链表下一个结点的指针。
- 参数 phead 是单链表头结点的指针。
- 参数 ptail 是单链表尾结点的指针,头、尾结点指针进行比较以预防资源句柄卷绕。
这两个函数都是资源缓冲池分配函数,使用单链表实现,_list_mono_allocate_seq 函数相对 _list_mono_allocate 函数可预防资源句柄卷绕,如下图所示。
SylixOS 内核中有很多需要资源缓冲池管理的地方使用到 _list_mono_allocate 函数和 _list_mono_allocate_seq 函数。比如典型的空闲线程控制块的管理,创建一个线程就需要从空闲线程控制块链表中申请一个线程控制块,这时指向空闲线程控制块的“头指针”就需要将当前指向的线程控制块分配出去,然后“头指针”指向下一个空闲线程控制块以备后续线程控制块的分配。
单链表回收
#include <SylixOS.h>
VOID _list_mono_free (PLW_LIST_MONO *phead,
PLW_LIST_MONO pfree);
VOID _list_mono_free_seq (PLW_LIST_MONO *phead,
PLW_LIST_MONO *ptail,
PLW_LIST_MONO pfree);
函数 _list_mono_free 原型分析:
- 参数 phead 是单链表结点的“头指针”。
- 参数 pfree 是要回收的结点的指针。
函数 _list_mono_free_seq 原型分析:
- 参数 phead 是单链表结点的“头指针”。
- 参数 ptail 是单链表尾结点的指针,头、尾结点指针进行比较以预防资源句柄卷绕。
- 参数 pfree 是要回收的结点的指针。
这两个函数都是资源缓冲池回收函数,使用单链表实现,_list_mono_free_seq 函数相对 _list_mono_free 函数可预防资源句柄卷绕,如下图所示。
SylixOS 内核中有很多需要资源缓冲池管理的地方使用到 _list_mono_free 函数和 _list_mono_free_seq 函数。和空闲线程控制块的分配相反,删除一个线程就需要回收该线程占用的线程控制块,这时系统就会清空该线程控制块,然后再次“空闲”的线程控制块会被系统回收到空闲线程控制块链表中,即将回收的线程控制块插入空闲线程控制块管理链表的头部,链接到空闲线程控制块链表中以备再次被使用。