《Orange’S 一个操作系统的实现》分析之IPC
1.IPC消息转发机制
在Orange操作系统的IPC中,实现了一个系统任务(task_sys)用于进程之间的消息转发,它主要的工作就是:
1.接收任意进程发送的消息;
2.识别消息;
3.根据消息特性转发到特定进程;
其实,很显然,图1中的主角是task_sys,它主要的工作就是实现了“消息转发”。这一点很好理解。其源代码如表1所示。
表1. Task_sys源
PUBLIC void task_sys() { MESSAGE msg; while (1) { send_recv(RECEIVE, ANY, &msg); int src = msg.source;
switch (msg.type) { case GET_TICKS: msg.RETVAL = ticks; send_recv(SEND, src, &msg); break; default: panic("unknown msg type"); break; } } } |
现在消息转发机制我们知道了,但是某个进程的消息如何发送给task_sys?其他进程又如何从task_sys接收消息?那就不得不说到下面的IPC系统调用。
1.IPC系统调用框架
Orange操作系统的消息发送和接收都是通过一个内核实现的系统调用来完成的。这个系统调用就是:sys_sendrec。调用路径如下:
表2. IPC系统调用路径
send_recv --> sendrec系统调用 --> sys_sendrec --> msg_send (发送消息进程调用路径) | ` -------> msg_receive(接收消息进程调用路径) |
其实,从表2可以知道,sys_sendrec这个系统调用主要通过调用msg_send和msg_receive这两个函数分别来实现消息的发送和接收。
2.消息发送和接收机制
表3. 消息发送和接收
msg_send |
|
msg_receive |
|
1.接收进程正在等待消息,包括: a.当前发送进程发送的消息 b.任意发送进程发送的消息 那么,就直接通过消息拷贝实现消息传递。 |
1.当前接收进程有可用消息 a.当前接收进程有来自硬件中断的消息
|
||
2.当前接收进程有可用消息 a.当前接收进程没有来自硬件中断的消息,并且该进程接收任意发送进程发送的消息 b.当前接收进程没有来自硬件中断的消息,并且该进程接收特定发送进程发送的消息 |
|||
3.当前进程没有可用消息(等价于msg_send中的情况1) |
|||
2.接收进程没有等待消息 那么,就将当前发送进程添加到接收进程的q_sending队列 |
通过将msg_send和msg_receive这两个函数的代码逻辑总结得到表3。通过表3,很容易可以明白消息发送与接收的相互作用机制。
“接收进程正在等待消息” 对应 “当前进程没有可以接收的消息”
“接收进程没有等待消息” 对应 “当前进程有可用消息”
4.硬件中断下的IPC
当硬件中断发送的时候,整个操作系统又是如何进行“消息”传递的呢?在Orange中,中断服务函数并不生成并发送msg结构体,而只是通知相关用户进程,数据已经就绪,那具体的数据在哪?数据是什么?这都与具体的应用有关。
除了以上不同之外,硬件中断下的IPC也使用一对函数来实现“消息”通信。
inform_int(TASK_HD);
interrupt_wait();
5.术语解释:
IPC —— inter process communication(进程间通信)