操作系统设计与实现:基于LoongArch架构
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

0.1.1 进程管理

在MaQueOS中,每个进程都由一个进程描述符管理,进程描述符对应process数据结构,如代码清单11.3所示。MaQueOS维护了一个用于管理系统中所有进程的进程描述符指针数组——process数组。某一时刻MaQueOS在系统中最多可以运行64个进程,因此process数组有64项。MaQueOS中运行的进程有4个状态:可运行状态(TASK_RUNNING)、可中断挂起状态(TASK_INTERRUPTIBLE)、不可中断挂起状态(TASK_UNINTERRUPTIBLE)和终止状态(TASK_EXIT)。

进程在运行过程中,可能运行在用户态或者内核态下。当进程运行在用户态下时,执行的是进程对应的应用程序的二进制可执行代码;当进程运行在内核态下时,执行的是内核的二进制可执行代码。不同进程运行各自的可执行代码,内核的可执行代码由所有进程共享。

进程通常在用户态下运行应用程序的可执行文件。当产生中断、例外或者主动调用系统调用(一种特殊的例外)后,进入内核态,当中断和例外处理完成后,再返回到用户态下运行。MaQueOS支持的中断详见0.1.5节。

MaQueOS支持基本的进程管理操作,包括进程创建与终止、进程挂起与唤醒以及进程调度。如图0.1所示,为了给应用程序提供基本的进程管理的功能,MaQueOS实现了4个系统调用:fork、exe、exit和pause。

1.进程创建

在MaQueOS中,除了第1个进程(进程0)由process_init函数进行初始化,其他所有进程都是通过该进程的父进程调用fork系统调用创建的。之后根据是否加载可执行文件,子进程分为两种情况:第一种情况是,父子进程使用相同的可执行文件,在这种情况下,只需要调用fork系统调用即可;第二种情况是,父子进程使用不同的可执行文件,在这种情况下,子进程还需要调用exe系统调用,加载子进程的可执行文件,同时释放和父进程共享的内容。

2.进程终止

子进程在结束运行前,通过调用exit系统调用,将自己的状态设置为终止状态(TASK_EXIT),再向父进程发送终止信号,之后调用进程切换函数。至此,子进程再也不会被调度运行,但是子进程占用的资源仍然没有被释放。当父进程接收到子进程发送的终止信号后,释放子进程占用的系统资源。

3.进程调度

为了能够在一个处理器上运行多个进程,MaQueOS将处理器的运行时间划分为以1秒为单位的时间片,并在进程创建和时间片用完时,为进程分配固定数量的时间片。当前进程的时间片用完后,MaQueOS提供的进程调度函数通过遍历process数组找到一个处于可运行状态(TASK_RUNNING)的进程,将其切换到处理器上运行。

4.进程挂起与唤醒

进程在运行过程中,会因为某些原因挂起。MaQueOS提供的进程挂起与唤醒机制涉及不可中断挂起唤醒和可中断挂起唤醒两种情况。

例如,在等待子进程终止运行时,父进程调用pause系统调用,通过将自己的状态设置为可中断挂起(TASK_INTERRUPTIBLE)来挂起该进程,当子进程给父进程发送终止信号后,父进程被唤醒,并释放子进程占用的资源。为了获取从键盘输入的字符,进程在用户态下调用input系统调用进入内核态,在input系统调用处理程序中,若检测到用于保存键盘输入字符的队列为空,则通过将进程的状态设置为不可中断挂起(TASK_UNINTERRUPTIBLE)来挂起该进程。当用户按下键盘上的按键后,键盘中断处理程序将等待键盘输入的该进程唤醒,该进程获取字符后,从内核态返回到用户态。

因此,两种进程挂起状态的区别是:处于可中断挂起状态的进程只能被信号唤醒;处于不可中断挂起状态的进程不能被信号唤醒,只能在等待的资源得到满足时才能被唤醒。

5.xt格式的可执行文件加载

MaQueOS仅支持加载运行xt格式的可执行文件。如图9.1所示,xt可执行文件包括两部分:xt可执行文件头和二进制可执行代码。其中,xt可执行文件头的大小为512B,二进制可执行代码的大小必须按4KB对齐。MaQueOS提供了一个脚本,用于将一个使用LoongArch汇编指令编写的汇编应用程序,通过编译链接生成一个可以在MaQueOS上运行的xt格式的可执行文件。如前所述,在进程创建过程中,进程在用户态下通过调用exe系统调用来实现对xt格式的可执行文件的加载。

6.基于共享内存的进程间通信

进程间通信指的是正在运行的进程之间通信的机制。进程间通信的机制有多种,MaQueOS采用的是基于共享内存的进程间通信机制。它的基本原理是:在物理内存中申请一个物理页,将其与需要通信的进程的虚拟页建立映射,并且将虚拟页的访问属性设置为可写,从而通过读写共享物理页达到进程间通信的目的。为了给应用程序提供基于共享内存的进程间通信的功能,MaQueOS实现shmem系统调用(如图0.1所示)。