SylixOS内核小巧,它提供的操作系统最基础的服务,这些服务包括:
1. 线程管理
2. 协程管理
3. 事件标志组管理
4. 中断管理
5. 调度器
6. 内存管理
7. 消息队列
8. 计数、互斥、二值信号量
9. 定时器管理
10. 资源回收器
这些最基础的功能构成了SylixOS所有功能与服务的核心。SylixOS本身是一个实时操作系统,所以内核调度器(scheduler)使用基于优先级的抢占式调度算法,调度器调度的基本单元为线程。SylixOS永远运行优先级最高的线程。
SylixOS调度器支持紧耦合同构多处理(SMP)并且调度器调度时间复杂度为O(1),换句话说,调度器每次调度消耗的时间与需要调度的线程总数量没有关系,即调度时间确定,这种系统适合于对时间有严格要求的工业与军事系统。此调度器同样支持同优先级线程,这些线程可按先进先出或者时间片轮转调度算法。
SylixOS线程(thread)有以下六种状态:
1. 初始化
2. 就绪
3. 运行
4. 阻塞
5. 僵死
6. 停止
线程各状态迁移顺序由下图所示:
【初始化】状态表示一个线程刚刚创建,操作系统为它分配了运行所必须的资源但是没有将它送入调度器。此时用户可以获取线程句柄,选择合适的时间启动线程。很多操作系统的线程没有这种状态。SylixOS加入这种状态主要是为了适应“静态系统”的要求,所谓静态系统就是运行线程确定,所需资源确定,行为确定的系统,例如汽车电子控制单元(ECU)系统。这类系统对响应和可靠性要求非常高,所以SylixOS可以提前分配好线程所有需要的资源,为它的运行做好一切准备,这样就不会因为资源短缺造成严重后果。
【就绪】状态表示一个线程可以被执行,即线程得到了除CPU以外运行所需要的所有资源,例如线程等待的信号量已经有效,这时线程请求调度器调度,至于调度器合适将CPU资源提供个这个线程以使其运行,则依赖于上面所说的调度器算法。
【运行】状态表示一个线程正在执行,即就绪后,系统调度器为这个线程分配了CPU资源使其得以运行。
【阻塞】状态表示线程现在不能继续执行,必须需要等待指定的事件发生,例如线程正在等待信号量有效,或者消息队列中的信息,或者一个信号,一个同步I/O请求等等。这个状态下线程得不到执行,除非等待的事件到达或者设置的超时时间到达,如果这两种情况发生,则线程进入就绪队列。等待调度器再次执行,同时将等待的结果告知用户代码。
【僵死】线程结束时需要回收操作系统在创建它时分配的资源,有些资源是它自身运行时无法回收的,例如内核对象,堆栈等,这时线程通知操作系统相关的回收器,并把自己设置为僵死状态等待回收器彻底销毁自己。
【停止】状态表示线程被其他线程或者系统强行暂停执行,此状态只有SMP系统会出现,当一个核正在运行的线程(或进程)向另一个核上的线程发送信号时,这时发送信号的目标线程正在另一个核上运行,则内核会自动将目标设置为停止状态,然后等信号发送完毕后再将这个任务恢复执行。
SylixOS系统上线程实体的状态永远是以上六种状态之一。
协程(coroutine),又称作协同程序是比线程还小的可执行代码序,在windows操作系统上称为纤程。一个线程内可以拥有多个协程,这些协程共享线程除了栈之外的所有资源,例如优先级,内核对象等等。由于线程内的所有协程共享线程本身的内核对象,所以调度器本身并不知道协程的存在,协程的运行是靠所属线程被调度时被执行的。一个线程内的协程共享所属线程的优先级,一个线程内部的协程不可被强占。只能轮转运行。而且当前正在运行协程必须主动放弃CPU另同线程内的另一个协程才能得以运行,当线程被删除时,线程内的所有协程也同时被全部删除。
SylixOS在内核中引入协程概念,而不是使用库模拟出的协程,这样SylixOS内部的协程管理更加便捷高效。
事件标志组(eventset)是SylixOS提供的一个线程同步通信机制。每一个事件标志组包含有32位事件标志,在应用中每一位可以代表一个事件,线程可以等待事件标志组中的一个事件或者同时等待多个事件。线程等待多个事件时既可以等待多个事件同时发生,也可以等待多个事件中任何一个事件的发生。指定的事件发生后,等待相应事件的线程将会从阻塞状态被转换成就绪状态。这时只要调度器调度该线程,它就可以执行。
SylixOS中断系统结构如下图所示,它本身可以支持无限数量的中断(interrupt)源,具体的中断向量表(interrupt vector)大小由编译时的配置决定。
SylixOS和大多数操作系统一样使用平板中断向量表,如果系统硬件中存在有主从级联中断,则需要在板级支持包(BSP)中进行相关的抽象。当系统发生中断时,BSP代码按操作系统要求处理好相关中断上下文(context)后,调用操作系统统一的中断入口API。操作系统根据中断向量号来决定运行哪些之前已经注册的中断服务。驱动程序不需要操作中断的具体行为,只需要注册相关的中断向量即可。
SylixOS同时支持单向量多中断服务函数表,所以像PCI总线这样的多级中断系统,使用此类中断向量管理,用户驱动程序将变的非常简单。
SylixOS调度器只管理一种资源:CPU。调度器决定当前时刻将CPU分配给哪个线程,即运行哪个线程。每一个CPU核心只能同时运行一个线程,如果没有任何就绪的用户线程,则调度器让CPU运行永远就绪的空闲(idle)线程。
如上所述,对于单核CPU系统,一般的多任务操作系统在宏观上是多任务并行处理,但在微观上,同时只有一个线程运行。调度器根据调度算法和当前就绪线程的相关参数来判断谁将运行。对于紧耦合多CPU系统(SMP,例如酷睿,龙芯多核),他们可以同时运行与内核数量相当的线程,例如双核处理器可以同时运行两个线程,如果这两个线程没有资源冲突,则理论运行速度将达到单核两倍(真正的并行处理系统),但是没有资源冲突的线程是理想状态,所以真实运行的N核系统是不可能达到单核系统N倍的效率。对于多核系统,SylixOS调度器将决定这些核同时运行哪些线程。对于硬实时的SylixOS来说,调度器将CPU分配给就绪线程中优先级最高的几个线程,这个调度算法时间复杂度也为O(1)。
SylixOS提供三种形式的内存管理:堆内存管理(heap),定长分区内存管理(pool),虚拟内存管理(vmm)。这三种内存管理有着不同的用途。
堆内存管理类似于我们常用的malloc、free操作,操作系统有两个非常关键的内存堆:“内核内存堆”和“系统内存堆”。内核堆负责系统内核对象的缓冲。系统堆负责内核基础缓冲区,驱动程序缓冲区等。
虚拟内存管理只用于有硬件内存管理单元(MMU)的处理器。它管理了整个虚拟内存空间和物理页面的分配,回收,映射,权限。是操作系统内存管理的核心。例如后面将要提到的进程,文件映射,缺页中断系统等等,都需要虚拟内存管理的支持。同时它也接管了所有内存的异常访问处理(映射错误或者权限错误)。
SylixOS物理内存采用页式内存管理算法。物理页面使用伙伴算法,虚拟空间采用哈希红黑二叉树保证分配与回收的速度。
消息队列是SylixOS提供的多任务同步通信方式之一,它将一个消息从一个任务传递到另一个任务,这样一个线程可以将产生的数据或者事件发送出去,由指定的任务继续处理。这也是操作系统多任务最常用的同步通信方式。
信号量也是SylixOS提供的多任务同步通信方式之一,SylixOS的信号量分为三种:计数信号量、二值信号量、互斥信号量。信号量既可以用作任务间的通信,也可以用于中断与任务的通信。SylixOS有关信号量对线程状态的影响如下图所示。
计数信号量内部是一个32/64位计数器,当计数值为0时等待的线程将被阻塞,如果不为0则计数器减一线程继续运行。发送信号量时,如果此时有线程阻塞在对应的信号量上,则阻塞的任务将被激活,如果没有则计数器加一。
二值信号量顾名思义,它只有两种状态:有效和无效。线程等待此信号量时如果信号量有效,则信号量立即变为无效状态,同时当前线程不阻塞并继续执行。如果信号量是无效状态,则线程被阻塞。发送信号量时,如果此时有线程阻塞在对应的信号量上,则阻塞的线程将被激活,如果没有等待此信号量的线程,则将信号量置为有效状态。
互斥信号量(简称互斥量)是SylixOS为保护共享资源设计的一种锁机制(大多数操作系统拥有此功能),互斥信号量的基本行为类似于二值信号量,但是功能更加强大。但它并不能取代二值信号量,因为释放互斥信号量的线程必须是之前获取该信号量的线程,所以互斥量不能被用作线程同步通信。SylixOS的互斥量提供两种方法避免优先级倒置(又名优先级反转),一种是优先级继承算法,一种是优先级天花板算法,创建互斥量时通过选项来选择需要使用的算法。同时互斥量支持资源死锁检测,死锁可重入功能,同样也是根据创建选项确定。
SylixOS提供两种类型的定时器:高速内核定时器,任务级定时器。高速内核定时器顾名思义,它的定时周期可以非常短,频率可以高过操作系统的时钟。但需要注意的是,高速定时器的用户回调函数可能运行在中断上下文中(由BSP代码决定),所以只能进行简单的操作,一般用于发送信号量激活等待线程,或者通知什么事情发生。
任务级定时器速度较慢,他提供普通精度的定时要求。定时器服务函数运行在操作系统t_timer内核线程中。
需要注意的是:SylixOS内核提供的定时器只用于内核模块或者内核应用,进程需要使用与信号系统相关的posix定时器。
SylixOS的回收器主要是记录一个进程的资源使用情况,在进程退出时将释放进程的所有资源,它们包括内核对象,文件描述符,进程空间,依赖的动态链接库等等。进程相关的内容将在下面进程一节详细讲解。
(本篇结束)