读书人

(莱昂氏unix源代码分析导读-27) Swap

发布时间: 2012-08-30 09:55:54 作者: rapoo

(莱昂氏unix源代码分析导读-27) Swap in/out (上)

By cszhao1980

Swap in/out指的是进程在物理内存(core空间)和磁盘交换文件间的双向移动过程,进程在active状态时,

其segment必然被swap in内存空间(core空间),而一旦处于非活动状态就有可能被swap out到磁盘交换

文件中。换进换出的过程必然涉及到磁盘io——这可看作是比较低层的操作,因此,这部分内容可以分

为两部分:高层的模型和低层的实际io。

1 高层模型

Unix使用“swapmap”这个高层模型来记录swap区域,swapmap类似coremap,都是map结构:

2515: struct map

2516: {

2517: char *m_size;

2518: char *m_addr;

2519: };

区别是:

(1) swap map的m_size的单位是“磁盘块”,即512个字节;

(2) swap map的m_addr为“磁盘块号”——而不是内存block号。

使用“swapmap”来管理swap空间有一个巨大的好处——同“coremap”一样,对空间资源

的管理可以通过高层函数malloc()和free()来实现。

整个swap区域由main函数初始化:

1583: mfree(swapmap, nswap, swplo);

4697: int swplo 4000; /* cannot be zero */

4698: int nswap 872;

因此,swap区域即定义为自磁盘第4000块开始,连续872个块。

在进行换进换出时,必须包括进程的“私有空间”——也被称为“swappable image”,

在proc表项里记录了它的地址和大小:

0371: int p_addr; /* address ofswappable image*/

0372: int p_size; /* size of swappable image (*64 bytes) */

但对可共享的text segment,情况就复杂一些。由于多个进程可以共享同一个text segment,即使进程被换进

或换出也不一定需要相应的换进或换出其text segment。系统定义了text表来帮助进行swap,每个进程都拥

有自己的text表项,而proc表项里的p_textp就指向该该表项。

4306: struct text

4307: {

4308: int x_daddr; /* disk address of segment */

4309: int x_caddr; /* core address, if loaded */

4310: int x_size; /* size (*64) */

4311: int *x_iptr; /* inode of prototype */

4312: char x_count; /* reference count */

4313: char x_ccount; /* number of loaded references */

4314: } text[NTEXT];

由于text segment是可共享的,因此,text struct中有两个引用计数;

(1) x_count —— 进程计数,使用该text的进程数量;

(2) x_ccount ——活动进程计数,使用该text segment且Loaded的进程数量;

显然,当“活动进程计数”减至0时,就应该将text segment从core空间中清除掉——text segment

总是在swap空间中保留副本,故无需被换出;而如果“进程计数”也为0时,磁盘交换文件中

也不该再保留此text segment了。

xccdec用来减少“活动进程计数”,显然,当进程换出时,就应该调用此函数,当活动进程计数

减至0时,就应该调用mfree(coremap,…),将text段从core空间中clear掉。

4490: xccdec(xp)

4491: int *xp;

4492: {

4493: register *rp;

4494:

4495: if((rp=xp)!=NULL && rp->x_ccount!=0)

4496: if(--rp->x_ccount == 0)

4497: mfree(coremap, rp->x_size, rp->x_caddr);

4498: }

当进程退出时,应该调用xfree函数,不仅会减少“活动进程计数”,还会减少“进程计数”。

4398: xfree()

4399: {

4400: register *xp, *ip;

4401:

4402: if((xp=u.u_procp->p_textp) != NULL) {

4403: u.u_procp->p_textp = NULL;

4404: xccdec(xp);

4405: if(--xp->x_count == 0) {

4406: ip = xp->x_iptr;

4407: if((ip->i_mode&ISVTX) == 0) {

4408: xp->x_iptr = NULL;

4409: mfree(swapmap, (xp->x_size+7)/8, xp->x_daddr);

4410: ip->i_flag =& ~ITEXT;

4411: iput(ip);

4412: }

4413: }

4414: }

4415: }

而当进程计数为0后,swap文件空间也会被free掉——为了效率起见,对于经常调用的程序设置了

“黏着位”ISVTX,即使进程计数为0,也会保留在swap空间。

博客地址:http://blog.csdn.net/cszhao1980

博客专栏地址:http://blog.csdn.net/column/details/lions-unix.html

读书人网 >UNIXLINUX

热点推荐