给 Minix 内核的进程消息计数
2009年10月20日 | 标签: minix, Minix Kernel
Minix 是个有别于 Linux 单内核的微内核操作系统,系统各个模块之间采用发消息的方式互相通信。在这本经典操作系统书:Operating Systems Design and Implementation, 3/E 的第219页有个练习题:
44. Add code to the MINIX 3 kernel to keep track of the number of messages sent from process (or task) i to process (or task) j. Print this matrix when the F4 key is hit.
这个练习题要比修改 Minix 内核的进程调度简单多了,只需要:
- 为每个进程初始化一个计数器;
- 在每次进程发消息的时候计数;
- 找到 Minix 在什么地方触发 F4 键,并把每个进程的计数器打印出来就可以了。
代码
在 proc.h 的 proc 进程数据结构里定义一个计数器 p_mess[NR_TASKS + NR_PROCS]:
struct proc { ... unsigned long p_mess[NR_TASKS + NR_PROCS]; };
在 main.c 的 main 里初始化计数器:
for (j = 0; j < NR_TASKS + NR_PROCS; j++) rp->p_mess[j] = 0;
在 proc.c 的 sys_call 里计数:
switch(function) { case SENDREC: /* A flag is set so that notifications cannot interrupt SENDREC. */ priv(caller_ptr)->s_flags |= SENDREC_BUSY; /* fall through */ case SEND: result = mini_send(caller_ptr, src_dst, m_ptr, flags); if (function == SEND || result != OK) { break; /* done, or SEND failed */ } /* fall through for SENDREC */ if (result == OK) rp->p_mess[NR_TASKS+src_dst]++; case RECEIVE: if (function == RECEIVE) priv(caller_ptr)->s_flags &= ~SENDREC_BUSY; result = mini_receive(caller_ptr, src_dst, m_ptr, flags); break; case NOTIFY: result = mini_notify(caller_ptr, src_dst); break; case ECHO: CopyMess(caller_ptr->p_nr, caller_ptr, m_ptr, caller_ptr, m_ptr); result = OK; break; default: result = EBADCALL; /* illegal system call */ }
最后按 F4 打印出来,修改 dmp_kernel.c 的 privileges_dmp:
printf("\n---- message track table dump ----\n\n"); printf("-nr- ", proc_nr(rp)); for (rp = oldrp; rp < oldrp+10; rp++) { printf("[%2d] ", proc_nr(rp)); } printf("\n"); /*for (rp = oldrp; rp < END_PROC_ADDR; rp++) {*/ for (rp = oldrp; rp < oldrp+10; rp++) { if (isemptyp(rp)) continue; printf("\n[%2d] %-7.7s ", proc_nr(rp), rp->p_name); for (i = 0; i < 10; i++) { printf(" %4lu ", rp->p_mess[i]); rp->p_mess[i] = 0; } }
编译内核和服务,并重新用新内核启动:
# cd /usr/src/tools # make clean # make hdboot; make services # reboot
注意:如果修改了 proc.h 文件,一定要 make clean 以后再 make hdboot; make services 编译内核和服务以后才能正常启动,如果没有修改 proc.h 只修改了 .c 文件可以只 make hdboot.