x01.os.11: IPC 路线图

学习的最好方法就是看代码,所以我们不妨跟着 IPC 的调用路线图,来学习学习 IPC。

x01.Lab.Download 下载代码后,首先进入 main.c 文件,在 TestA 中,有这么一句:Print("<Ticks:%x>", GetTicksIPC()); 其中,GetTicksIPC 就是通过 IPC 获取时间 tick 数。进入 GetTicksIPC,会看到如下代码:

1     m.type = M_GetTicks;
2     _SendReceive(M_Both, T_IPC, &m);
3     return m.M_RetValue;    

_SendReceive 是对 syscall.s 文件中的 SendReceive 封装。调用 SendReceive 会产生一个中断而进入 SysSendReceive(在 proc.c 文件中)。顾名思义,SysSendReceive 根据消息类型,进行相应处理。现在有个问题,就是消息不止一种,每种又不止一个,处理这么多消息,需要有个生生不息的发动机。这个发动机,就是 IPC 任务,进入 ipc.c 文件,可看到如下代码:

 1 #include "kstd.h"
 2 
 3 void TaskIPC() {
 4     Message    msg;
 5     while (1) {
 6         _SendReceive(M_Receive, T_Any, &msg);
 7         int src = msg.source;
 8         switch (msg.type) {
 9         case M_GetTicks:
10             msg.M_RetValue = g_Ticks;
11             _SendReceive(M_Send, src, &msg);
12             break;
13         default:
14             Panic("Unknown message type!");
15             break;
16         }
17     }
18 }

这一下就明白了,原来,在 TaskIPC 中,先接收所有的消息,再根据消息的类型进行处理,处理后的结果由 _SendReceive 发送出去。这同微软的消息处理机制如出一辙。

TaskIPC 在任务表中,由 Schedule 进行调用。而 Schedule 则由时钟中断周而复始的调用之。生生不息的机制原来在此!

由终端进入工程目录,makebochs,可看到效果图如下:

    

看来,我们的 IPC 机制,已然发挥作用了。

不过,说实话,这套消息机制,看起来优雅,但多了几次调用,效率是大打折扣的。从设计看优雅,从实际看却不理想。二者不可兼得,还是要从实际出发。也难怪 Linux 要舍弃这套近乎完美的消息处理机制,而采用宏内核了。

posted on 2014-10-04 16:14  x01  阅读(967)  评论(0编辑  收藏  举报

导航