By cszhao1980
Swap in/out指的是进程在物理内存(core空间)和磁盘交换文件间的双向移动过程,进程在active状态时,
其segment必然被swap in内存空间(core空间),而一旦处于非活动状态就有可能被swap out到磁盘交换
文件中。换进换出的过程必然涉及到磁盘io——这可看作是比较低层的操作,因此,这部分内容可以分
为两部分:高层的模型和低层的实际io。
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